Czy operator rzutowania może być jawny?

84

Jeśli chodzi o konstruktory, dodanie słowa kluczowego explicituniemożliwia entuzjastycznemu kompilatorowi utworzenie obiektu, gdy nie było to pierwszym zamiarem programisty. Czy taki mechanizm jest dostępny również dla operatorów odlewów?

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

Tutaj, na przykład, chciałbym móc rzucać Foow a std::string, ale nie chcę, aby takie rzucanie miało miejsce w sposób pośredni.

qdii
źródło

Odpowiedzi:

101

Tak i nie.

To zależy od używanej wersji C ++.

  • C ++ 98 i C ++ 03 nie obsługują explicitoperatorów konwersji typów
  • Ale C ++ 11 tak.

Przykład,

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 
}

Skompiluj go z g++ -std=c++0x, pojawi się ten błąd:

prog.cpp: 13:20: błąd: zażądano konwersji z „A” do typu nieskalarnego „std :: string”

Demo online: http://ideone.com/DJut1

Ale jak tylko napiszesz:

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

Błąd znika: http://ideone.com/LhuFd

BTW, w C ++ 11 jawny operator konwersji jest nazywany „kontekstowym operatorem konwersji”, jeśli konwertuje na wartość logiczną . Ponadto, jeśli chcesz dowiedzieć się więcej o niejawnych i jawnych konwersjach, przeczytaj ten temat:

Mam nadzieję, że to pomoże.

Nawaz
źródło
9
Nawet w C ++ 03 można łatwo uniknąć niejawnej konwersji. Po prostu wywołaj funkcję toString, a nie operator std::string. Oczywiście może to powodować problemy z niektórymi szablonami. Zawsze używałem toStringi nigdy nie sprawiało mi to żadnych problemów, ale wyobrażam sobie, że może to zależeć od twojego stylu kodowania.
James Kanze
@MatthieuM. Tak jak operator std::string():-).
James Kanze
2
Używam to_stringzamiast tego. Pomaga, że ​​tak to nazywa C ++ 11, więc pomaga pisać kod zgodny z przyszłymi wersjami i pomaga w szablonach.
Luis Machuca
1
std::string s(a)lub std::string s{a}powinien również działać jako static_cast<std::string>(a).
alfC
2
@Bin: Ponieważ explicit operator bool() jest wywoływane kontekstowo przez kompilator podczas pisania if(std::cin). Zauważ, że zachodząca tutaj konwersja jest (nieformalnie) nazywana konwersją kontekstową , a nie konwersją niejawną .
Nawaz,