Template function in class
我不知道该怎么办。我总是通过使用一个简单的类和一个简单的模板函数得到一个错误。我读了所有其他的解决方案,但它们没有帮助我。
除了一些其他类,我还有一些简单的类数据:
1 2 3 4 5 6 7 8 9 10 11 | class Data{ public: template <class T> T dat(); int id; union{ char c; int i; double d; }; }; |
以及函数dat:
1 2 3 4 5 6 | template <class T> T Data::dat(){ if(id == 1) return i; if(id == 2) return d; if(id == 3) return c; } |
如您所见,我想检查ID并返回int、double或char。现在我试着打印主函数中的值,如下所示:
1 2 3 4 | Data test; test.id=1; test.i = 12; cout<<test.dat(); |
但我总是收到这个错误消息:
1 | Error: Could not find a match for Data::dat<Data::T>() needed in main(int, char**). |
问题出在哪里??
谢谢你
要准确地说,您希望函数的返回类型取决于对象中的
I don't know what to do. I always get an error by using a simple class and a simple template function. I read all the other solutions but they didn't helped me.
在我看来,你想建立一个有歧视的联盟。
因为模板函数的返回类型是在编译时确定的(即在ID中设置值并尝试调用函数之前),所以您的实现无法工作。
解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | class Data { enum value_type { int_val, char_val, double_val } discriminator; // private (the user doesn't see this) // this replaces your id union{ char c; int i; double d; } value; public: class wrong_type_error: public std::logic_error { public: wrong_type_error(const std::string& msg): std::logic_error(msg) {} }; explicit Data(const char c) : discriminator(Data::char_value) , value.c(c) { } explicit Data(const int i) : discriminator(Data::int_value) , value.i(i) { } explicit Data(const double d) : discriminator(Data::double_value) , value.d(d) { } // don't put this here: int id; // this part can be optimized to simpler (more idiomatic) code template<typename T> T get() const; // undefined template<> int get() const { if(discriminator != Data::int_val) throw wrong_type_error("Cannot return a int from Data instance"); return value.i; } template<> char get() const { if(discriminator != Data::char_val) throw wrong_type_error("Cannot return a char from Data instance"); return value.c; } template<> double get() const { if(discriminator != Data::double_val) throw wrong_type_error("Cannot return a double from Data instance"); return value.d; } }; |
客户端代码:
1 2 | Data test(10.5); cout<<test.get<double>(); |
尽管如此,根据您的需要,您应该考虑使用boost::variant或boost::any实例。
1 | cout << test.dat<int>(); |
另外,请记住,您必须在头文件中实现
使用此:
1 | cout<<test.dat<int>(); |
VS2012表示"错误C2783:'t data::dat(void)':无法推导't'的模板参数。"
您只需要告诉函数
1 | cout<<test.dat<int>(); |
如果传递模板化参数,则可以推导模板类型,但不能猜测返回类型。