7
#include <iostream>
using namespace std;

class Foo{

        string _s;
        public:
        Foo(string ss){
                _s = ss;
        }
        Foo& operator=(bool b){
                cout << "bool" << endl;
                return *this;
        }
        Foo& operator=(const string& ss){
                cout << "another one" << endl;
                return *this;
        }
};


int main(){

        Foo f("bar");
        f = "this";
        return 0;

}

我重载了=运算符。我期望f = "this";语句调用operator=(const string& ss)重载。但事实并非如此。它称为operator=(bool b)重载。为什么?

4

4 回答 4

13

此运算符operator=(const string& ss)需要对参数 ( const char*to std::string) 的用户定义类型进行转换,而bool版本没有,因此提供了更好的匹配:您可以从内置类型转换const char[5]const char*to bool

于 2013-03-04T21:42:39.353 回答
1

正如另一个答案所指出的,bool转换的指针是首选,因为它不涉及用户定义的转换,而std::string转换中包含用户定义的转换。

C++11 提供了手动类型控制的能力。

template<size_t n>
struct enumarated_enum {
private:
  enum empty {};
};

template<bool b, size_t n=0>
using EnableIf = typename std::enable_if< b, typename enumerated_enum<n>::empty >::type;

template<typename String, EnableIf< std::is_convertible< String, std::string >::value >... >
Foo& operator=(String&& s) {
  cout << "string overload" << "\n";
}

// either this:
template<typename Bool, EnableIf< !std::is_convertible< Bool, std::string >::value && std::is_convertible< Bool, bool >::value, 1 >... >
Foo& operator=(Bool&& b) {
  cout << "bool overload" << "\n";
}
// or this:
Foo& operator=(bool b) {
  cout << "bool overload" << "\n";
}

如果可以将类型转换为 a ,我们将完美匹配该类型,如果无法转换为std::string模板,则模板不匹配,std::string并且查看其他重载。

如果您希望能够支持多种类型,则必须使用长逻辑形式来描述您要运行的重载,并确保其他类型不接受它(使用上面的 not 构造)。如果您只有两种类型,则第二种类型可以是传统的重载。模板重载首先破解与传统重载不完全匹配的任何内容......

(第二个模板参数是一个enum不存在的编号 s 的可变列表,其唯一目的是确保两个模板有足够的差异,编译器不会抱怨。)

于 2013-03-04T22:15:50.827 回答
0

在不深入研究 C++ 标准的情况下,从表面上看,您的问题是,您使用 string& 和 bool 定义了分配重载,但在测试中您分配了一个 char* 数组。

因此,如果您定义一个字符串并分配,它将按预期工作。

检查它在这里工作:http ://codepad.org/owb6noXR

于 2013-03-04T21:47:33.323 回答
0

正如其他人所说,解决此问题的一个简单方法是在执行运算符时简单地将字符串转换为std::string, ,以便 C++ 确切知道要选择哪个重载:

#include <iostream>
using namespace std;

class Foo{

        string _s;
        public:
        Foo(string ss){
                _s = ss;
        }
        Foo& operator=(bool b){
                cout << "bool" << endl;
                return *this;
        }
        Foo& operator=(const string& ss){
                cout << "another one" << endl;
                return *this;
        }
};


int main(){

        Foo f((string)"bar");
        f = (string)"this";
        return 0;

}
于 2013-03-04T22:09:11.707 回答