如下代码报error C2228: left of '.str' must have class/struct/union
#include <string>
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
class ValueBox {
private:
T value;
private:
template<typename U,
typename std::enable_if<std::is_class<U>::value && !std::is_same<U, string>::value, U>::type* = nullptr,
typename std::enable_if<!class_str<U>::ret, U>::type* = nullptr>
std::string str(const T&) {
cout << "1.---------------------" << endl;
return "null";
};
template<typename U,
typename std::enable_if<std::is_class<U>::value && std::is_same<U, string>::value, U>::type* = nullptr>
std::string str(const T&) {
cout << "2.---------------------" << endl;
return value;
};
template<typename U,
typename std::enable_if<std::is_class<U>::value && !std::is_same<U, string>::value, U>::type* = nullptr,
typename std::enable_if<class_str<U>::ret, U>::type* = nullptr>
std::string str(const T&) {
cout << "3.---------------------" << endl;
return value.str();
};
template<typename U,
typename std::enable_if<!std::is_class<U>::value && std::is_arithmetic<U>::value, U>::type* = nullptr>
std::string str(const T&) {
cout << "4.---------------------" << endl;
return std::to_string(value);
};
public:
ValueBox(const T& _value) : value(_value) {
}
const T& getValue() const {
return value;
};
T& getValue() {
return value;
};
std::string str() {
return str<T>(value);
};
};
int main() {
ValueBox<string> s("sddds");
cout << s.str() << endl;
ValueBox<bool> j ( true);
cout << j.str() << endl;
ValueBox<int> i(100);
cout << i.str() << endl;
ValueBox<float> f ( 10.6f);
cout << f.str() << endl;
ValueBox<Box> b1 (Box());
cout << b1.str() << endl;
ValueBox<Bin> b2 (Bin());
cout << b2.str() << endl;
return 1;
}
报错的原因是C++ 编译器把ValueBox<Box> b1 (Box());中的b1看成的函数定义,把Box()看成是返回值为Box的无参数函数,只不过此时的参数名称未定义罢了。这种错误有一个通用的名称,叫做:Most Vexing Parse
修改的方法有如下几种:
1、将Box单独放一行并初始化
Box b; // 不能使用Box b();,这样b又会被当成函数定义了
ValueBox<Box> b1 (b);
2、将Box()用括号包起来,这样Box()就不会被看成是函数了
ValueBox<Box> b1 ((Box()));
3、使用C++1中的统一初始化语法,即使用{}
ValueBox<Box> b1 {Box()};
参考文档
C++语法分析中最让人头疼的歧义
Item 6. Be alert for C++'s most vexing parse
Effective STL 笔记: Item 6--Be alert for C++'s most vexing parse