ข้อกำหนดภาษาอนุญาตให้นำไปใช้งานได้<cmath>โดยการประกาศ (และกำหนด) ฟังก์ชันมาตรฐานในเนมสเปซส่วนกลางจากนั้นนำเข้าสู่เนมสเปซstdโดยใช้การประกาศ ไม่มีการระบุว่าใช้แนวทางนี้หรือไม่
  20.5.1.2 ส่วนหัว
  4 [ ... ] ในห้องสมุดมาตรฐาน c ++ อย่างไรก็ตามการประกาศ (ยกเว้นสำหรับชื่อซึ่งจะถูกกำหนดเป็นแมโครใน C) อยู่ในขอบเขต namespace (6.3.6) ของการ stdnamespace ไม่มีการระบุว่าชื่อเหล่านี้ (รวมถึงการโอเวอร์โหลดใด ๆ ที่เพิ่มในข้อ 21 ถึง 33 และภาคผนวก D) ถูกประกาศครั้งแรกภายในขอบเขตเนมสเปซส่วนกลางจากนั้นจะถูกฉีดเข้าไปในเนมสเปซstdโดยใช้การประกาศอย่างชัดเจน (10.3.3)
เห็นได้ชัดว่าคุณกำลังเผชิญกับการใช้งานอย่างใดอย่างหนึ่งที่ตัดสินใจทำตามแนวทางนี้ (เช่น GCC) คือการดำเนินงานของคุณมี::absในขณะที่std::absเพียงแค่ "หมายถึง" ::absเพื่อ
คำถามหนึ่งที่ยังคงอยู่ในกรณีนี้คือทำไมนอกเหนือจากมาตรฐานที่::absคุณสามารถประกาศของคุณเอง::absได้นั่นคือเหตุใดจึงไม่มีข้อผิดพลาดในการนิยามหลายข้อ ซึ่งอาจเกิดจากคุณลักษณะอื่นที่มีให้โดยการนำไปใช้งานบางอย่าง (เช่น GCC): พวกเขาประกาศฟังก์ชันมาตรฐานที่เรียกว่าสัญลักษณ์ที่อ่อนแอดังนั้นคุณจึงสามารถ "แทนที่" ด้วยคำจำกัดความของคุณเองได้
ทั้งสองปัจจัยร่วมกันสร้างผลที่คุณสังเกต: การเปลี่ยนอ่อนแอสัญลักษณ์ของยังส่งผลในการเปลี่ยน::abs std::absสิ่งนี้สอดคล้องกับมาตรฐานภาษาอย่างไรเป็นเรื่องที่แตกต่างกัน ... ไม่ว่าในกรณีใดอย่าพึ่งพาพฤติกรรมนี้ - ภาษานี้ไม่รับประกัน
ใน GCC พฤติกรรมนี้สามารถทำซ้ำได้โดยใช้ตัวอย่างที่เรียบง่ายต่อไปนี้ ซอร์สไฟล์เดียว
#include <iostream>
void foo() __attribute__((weak));
void foo() { std::cout << "Hello!" << std::endl; }
ซอร์สไฟล์อื่น
#include <iostream>
void foo();
namespace N { using ::foo; }
void foo() { std::cout << "Goodbye!" << std::endl; }
int main()
{
  foo();
  N::foo();
}
ในกรณีนี้คุณจะสังเกตได้ว่านิยามใหม่ของ::foo( "Goodbye!") ในไฟล์ต้นฉบับที่สองมีผลต่อพฤติกรรมของN::foo. "Goodbye!"ทั้งเรียกร้องให้ส่งออกจะ และถ้าคุณเอาความหมายของ::fooจากแฟ้มแหล่งที่มาที่สองสายทั้งสองจะส่งถึงคำนิยาม "ต้นฉบับ" ของและเอาท์พุท::foo"Hello!"
ได้รับอนุญาตที่ได้รับจากข้างต้น 20.5.1.2/4 <cmath>จะมีการดำเนินการลดความซับซ้อนของ การใช้งานได้รับอนุญาตให้รวม C-style <math.h>จากนั้นประกาศฟังก์ชันใหม่stdและเพิ่ม C ++ - การเพิ่มและปรับแต่งเฉพาะบางอย่าง หากคำอธิบายข้างต้นอธิบายกลไกภายในของปัญหาอย่างถูกต้องส่วนสำคัญจะขึ้นอยู่กับความสามารถในการเปลี่ยนสัญลักษณ์ที่อ่อนแอสำหรับฟังก์ชันเวอร์ชัน C
โปรดทราบว่าถ้าเราเพียงแค่ทั่วโลกแทนที่intด้วยdoubleในโปรแกรมดังกล่าวข้างต้นรหัส (ภายใต้ GCC) จะทำงาน "ตามที่คาดไว้" - -5 5มันจะออก สิ่งนี้เกิดขึ้นเนื่องจากไลบรารีมาตรฐาน C ไม่มีabs(double)ฟังก์ชัน โดยการประกาศของเราเองabs(double)เราไม่ได้แทนที่อะไร
แต่ถ้าหลังจากเปลี่ยนจากintด้วยdoubleเราก็เปลี่ยนจากabsไปfabsเป็นพฤติกรรมแปลก ๆ ดั้งเดิมจะปรากฏขึ้นอีกครั้งในรัศมีภาพ (เอาต์พุต-5 -5)
สิ่งนี้สอดคล้องกับคำอธิบายข้างต้น
     
              
absไม่ถูกต้อง