【问题标题】:Why doesn't the compiler perform a type conversion?为什么编译器不执行类型转换?
【发布时间】:2011-10-10 22:01:10
【问题描述】:

考虑下面的代码。

#include <iostream>
#include <string>

struct SimpleStruct
{
    operator std::string () { return value; }
    std::string value;
};

int main ()
{
    std::string s;    // An empty string.
    SimpleStruct x;   // x.value constructed as an empty string.

    bool less = s < x; // Error here.
    return 0;
}

此代码不能在 g++ 或 Microsoft Visual C++ 上编译。编译器给出的错误报告是no match for operator '&lt;' in 's &lt; x'。问题是为什么编译器不简单地将SimpleStruct x 转换成string 根据给定的operator string () 再使用operator &lt; ( string, string )

【问题讨论】:

    标签: c++ operators type-conversion


    【解决方案1】:

    operator&lt; for std::string 是一个函数模板。重载是:

      template<class charT, class traits, class Allocator>
        bool operator< (const basic_string<charT,traits,Allocator>& lhs,
                const basic_string<charT,traits,Allocator>& rhs);
      template<class charT, class traits, class Allocator>
        bool operator< (const basic_string<charT,traits,Allocator>& lhs,
                const charT* rhs);
      template<class charT, class traits, class Allocator>
        bool operator< (const charT* lhs,
                const basic_string<charT,traits,Allocator>& rhs);
    

    您的调用与任何可用的重载都不匹配,因此它们都从候选列表中删除。由于没有选择函数模板作为解决调用的候选者,因此没有任何东西可以转换为 SimpleStruct。

    template <class T>
    class String
    {
    };
    
    template <class T>
    bool operator< (const String<T>&, const String<T>&) { return true; }
    
    
    //if a suitable non-template function is available, it can be picked
    //bool operator< (const String<char>&, const String<char>&) { return true; }
    
    struct SimpleStruct
    {
       operator String<char> () { return value; }
       String<char> value;
    };
    
    int main()
    {
        String<char> s;
        SimpleStruct ss;
        s < ss; //the call doesn't match the function template, leaving only the commented-out candidate
    }
    

    【讨论】:

    • +1,这个答案是正确的。 string::operator &lt;() 不把参数当作const string&amp;,而是basic_string&lt;&gt;;如果您在全局范围内重载operator &lt;,那么它可以工作。 ideone.com/vMERa
    • 嗯,std::string 只是std::basic_string&lt;char&gt; 的类型定义。 typedef 不引入新类型,因此不影响重载。
    • 根本问题是template&lt;class charT, class tr, class Alloc&gt; bool operator&lt; (std::basic_string&lt;charT, tr,Alloc&gt; const&amp; lhs, std::basic_string&lt;charT, tr, Alloc&gt; const&amp; rhs);中的charT推演失败。没有charTbasic_string&lt;charT&gt; 等于 SimpleStruct。这确实将其从重载集中删除。
    猜你喜欢
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多