C++ Implicit Conversion Operators Precedence

后端 未结 1 1177
悲哀的现实
悲哀的现实 2021-01-11 19:24

EDIT: Following Mike Seymour\'s comment, I replaced operator std::string () const; with operator char * () const; and changed the implementation ac

相关标签:
1条回答
  • 2021-01-11 19:54

    After I remove the operator unsigned long int, why do I need to cast x to std::string explicitly? Why does it not call the implicit cast operator (std::string) directly?

    The version of << for strings is a template, parametrised by the parameters of the std::basic_string template (std::string itself being a specialisation of that template). It can only be chosen by argument-dependent lookup, and that only works if the argument is actually a specialisation of std::basic_string, not something convertible to that.

    Is there any documentation that explains which implicit casts are allowed and which is their order of precedence?

    The rules are quite complex, and you'd need to read the C++ standard for the full story. Simple rules of thumb are that implicit conversions can't contain more than one user-defined conversion and (as you've found out) the result of an implicit conversion can't be used to choose a template specialisation by argument-dependent lookup.

    I am not sure I fully understand the associated caveats. Could somebody please outline them?

    I don't fully understand them either; the interactions between implicit conversions, name lookup and template specialisation (and probably other factors that I can't think of right now) are rather complex, and most people don't have the inclination to learn them all. There are quite a few instances where implicit conversion won't happen, and others where it might happen when you don't expect it; personally, I find it easier just to avoid implicit conversions most of the time.

    Would it be better practice to just define public methods ToUnsignedLongInt and ToString?

    That's probably a good idea, to avoid unwanted conversions. You can fix your problem by leaving them and use them explicitly when necessary:

    std::cout << std::string(x) << std::endl;
    

    In C++11, you can declare them explicit, so that they can only be used in this manner. In my opinion, that would be the best option if you can; otherwise, I would use explicit conversion functions as you suggest.

    By the way, the return type of main() must be int, not void.

    0 讨论(0)
提交回复
热议问题