ผู้ดำเนินการแคสต์สามารถเปิดเผยได้หรือไม่?


84

เมื่อพูดถึงคอนสตรัคเตอร์การเพิ่มคีย์เวิร์ดexplicitจะป้องกันไม่ให้คอมไพเลอร์ที่กระตือรือร้นสร้างอ็อบเจกต์เมื่อมันไม่ใช่ความตั้งใจแรกของโปรแกรมเมอร์ กลไกดังกล่าวมีให้สำหรับผู้ประกอบการหล่อด้วยหรือไม่?

struct Foo
{
    operator std::string() const;
};

ตัวอย่างเช่นที่นี่ฉันอยากจะร่ายFooเป็น a std::stringได้ แต่ฉันไม่ต้องการให้นักแสดงดังกล่าวเกิดขึ้นโดยปริยาย

คำตอบ:


101

ใช่และไม่.

ขึ้นอยู่กับเวอร์ชันของ C ++ ที่คุณใช้

  • C ++ 98 และ C ++ 03 ไม่รองรับexplicitตัวดำเนินการแปลงชนิด
  • แต่ C ++ 11 ทำ

ตัวอย่าง,

struct A
{
    //implicit conversion to int
    operator int() { return 100; }

    //explicit conversion to std::string
    explicit operator std::string() { return "explicit"; } 
};

int main() 
{
   A a;
   int i = a;  //ok - implicit conversion 
   std::string s = a; //error - requires explicit conversion 
}

รวบรวมด้วยg++ -std=c++0xคุณจะได้รับข้อผิดพลาดนี้:

prog.cpp: 13: 20: ข้อผิดพลาด: ขอการแปลงจาก 'A' เป็นประเภทที่ไม่ใช่สเกลาร์ 'std :: string'

การสาธิตออนไลน์: http://ideone.com/DJut1

แต่ทันทีที่คุณเขียน:

std::string s = static_cast<std::string>(a); //ok - explicit conversion 

ข้อผิดพลาดหายไป: http://ideone.com/LhuFd

BTW, ใน C ++ 11 ผู้ประกอบการแปลงอย่างชัดเจนจะเรียกว่าเป็น"ผู้ประกอบการแปลงบริบท"ถ้ามันจะแปลงไปเป็นแบบบูล นอกจากนี้หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับการแปลงโดยนัยและชัดเจนโปรดอ่านหัวข้อนี้:

หวังว่าจะช่วยได้


9
แม้ใน C ++ 03 คุณสามารถหลีกเลี่ยงการแปลงโดยปริยายได้อย่างง่ายดาย เพียงแค่เรียกใช้ฟังก์ชันมากกว่าtoString operator std::stringแน่นอนว่าสิ่งนี้อาจทำให้เกิดปัญหากับบางเทมเพลต ฉันใช้มาตลอดtoStringและมันไม่เคยทำให้ฉันมีปัญหา แต่ฉันคิดว่าสิ่งนี้อาจขึ้นอยู่กับรูปแบบการเข้ารหัสของคุณ
James Kanze

@MatthieuM. เช่นเดียวกับoperator std::string():-)
James Kanze

2
ฉันใช้to_stringแทน ช่วยให้มันเป็นสิ่งที่ C ++ 11 เรียกมันดังนั้นจึงช่วยเขียนโค้ดที่รองรับการส่งต่อและช่วยในเรื่องเทมเพลต
Luis Machuca

1
std::string s(a)หรือยังต้องทำงานเป็นstd::string s{a} static_cast<std::string>(a)
alfC

2
@Bin: เนื่องจากexplicit operator bool() ถูกเรียกตามบริบทif(std::cin)โดยรวบรวมเมื่อคุณเขียน โปรดสังเกตว่าการแปลงที่เกิดขึ้นที่นี่คือ (อย่างไม่เป็นทางการ) เรียกว่าการแปลงตามบริบทไม่ใช่ การแปลงโดยนัย
Nawaz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.