非静态数据成员class推导
Non-static data members class deduction
我正在尝试解决类型推导问题。
这是演示代码,使用函数重载来定义传递的变量是 int 还是 double
std::string tcast( const double &x){ return "Floating Point";};
std::string tcast( const int &x){ return "Integer";};
int main(){
double dA;
int iB;
std::cout << "Access to variable type \n";
std::cout << "dA : "<< tcast( dA )<< std::endl;
std::cout << "iB : "<< tcast( iB )<< std::endl;
}
Access to variable type
dA : Floating Point
iB : Integer
但此函数不适用于非静态 class 成员:
struct Foo{
double dA;
int iB;
};
int main(){
std::cout << "Member dA : "<< tprint( &Foo::dA )<< std::endl;
std::cout << "Member iB : "<< tprint( &Foo::iB )<< std::endl;
}
GCC 编译错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:111:44: error: no matching function for call to ‘tcast(double Foo::*)’
111 | std::cout << "dA : "<< tcast( &Foo::dA )<< std::endl;
| ^
main.cpp:96:13: note: candidate: ‘std::string tcast(const double&)’
96 | std::string tcast( const double &x){ return "Floating Point";};
| ^~~~~
main.cpp:96:34: note: no known conversion for argument 1 from ‘double Foo::*’ to ‘const double&’
96 | std::string tcast( const double &x){ return "Floating Point";};
| ~~~~~~~~~~~~~~^
main.cpp:97:13: note: candidate: ‘std::string tcast(const int&)’
97 | std::string tcast( const int &x){ return "Integer";};
| ^~~~~
main.cpp:97:34: note: no known conversion for argument 1 from ‘double Foo::*’ to ‘const int&’
97 | std::string tcast( const int &x){ return "Integer";};
| ~~~~~~~~~~~~~~^
但是下面的代码可以编译:
template <typename T>
std::string tprint( const T &x){ return typeid(x).name();};
...
std::cout << "dA : "<< tprint( dA )<< std::endl;
std::cout << "iB : "<< tprint( iB )<< std::endl;
std::cout << "Member dA : "<< tprint( &Foo::dA )<< std::endl;
std::cout << "Member iB : "<< tprint( &Foo::iB )<< std::endl;
因此编译器可以看到 dA 的类型为 double 和 iB int
dA : d
iB : i
Member dA : M3Food // ends in d
Member iB : M3Fooi // ends in i
那么如何推导非静态数据成员的类型才是正确的呢?
我们可以在这里利用 template argument deduction。指向成员数据语法的指针是
DataType Class::*Pointer
推导出成员类型后,我们可以调用所需的重载。
template<typename Class, typename MemType>
std::string tcast(MemType Class::*mData){
return tcast(MemType{});
}
您可以添加额外的重载:
template <typename C>
std::string tprint(double C::*){ return "member Floating Point";};
template <typename C>
std::string tprint(int C::*){ return "member Integer";};
我正在尝试解决类型推导问题。
这是演示代码,使用函数重载来定义传递的变量是 int 还是 double
std::string tcast( const double &x){ return "Floating Point";};
std::string tcast( const int &x){ return "Integer";};
int main(){
double dA;
int iB;
std::cout << "Access to variable type \n";
std::cout << "dA : "<< tcast( dA )<< std::endl;
std::cout << "iB : "<< tcast( iB )<< std::endl;
}
Access to variable type
dA : Floating Point
iB : Integer
但此函数不适用于非静态 class 成员:
struct Foo{
double dA;
int iB;
};
int main(){
std::cout << "Member dA : "<< tprint( &Foo::dA )<< std::endl;
std::cout << "Member iB : "<< tprint( &Foo::iB )<< std::endl;
}
GCC 编译错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:111:44: error: no matching function for call to ‘tcast(double Foo::*)’
111 | std::cout << "dA : "<< tcast( &Foo::dA )<< std::endl;
| ^
main.cpp:96:13: note: candidate: ‘std::string tcast(const double&)’
96 | std::string tcast( const double &x){ return "Floating Point";};
| ^~~~~
main.cpp:96:34: note: no known conversion for argument 1 from ‘double Foo::*’ to ‘const double&’
96 | std::string tcast( const double &x){ return "Floating Point";};
| ~~~~~~~~~~~~~~^
main.cpp:97:13: note: candidate: ‘std::string tcast(const int&)’
97 | std::string tcast( const int &x){ return "Integer";};
| ^~~~~
main.cpp:97:34: note: no known conversion for argument 1 from ‘double Foo::*’ to ‘const int&’
97 | std::string tcast( const int &x){ return "Integer";};
| ~~~~~~~~~~~~~~^
但是下面的代码可以编译:
template <typename T>
std::string tprint( const T &x){ return typeid(x).name();};
...
std::cout << "dA : "<< tprint( dA )<< std::endl;
std::cout << "iB : "<< tprint( iB )<< std::endl;
std::cout << "Member dA : "<< tprint( &Foo::dA )<< std::endl;
std::cout << "Member iB : "<< tprint( &Foo::iB )<< std::endl;
因此编译器可以看到 dA 的类型为 double 和 iB int
dA : d
iB : i
Member dA : M3Food // ends in d
Member iB : M3Fooi // ends in i
那么如何推导非静态数据成员的类型才是正确的呢?
我们可以在这里利用 template argument deduction。指向成员数据语法的指针是
DataType Class::*Pointer
推导出成员类型后,我们可以调用所需的重载。
template<typename Class, typename MemType>
std::string tcast(MemType Class::*mData){
return tcast(MemType{});
}
您可以添加额外的重载:
template <typename C>
std::string tprint(double C::*){ return "member Floating Point";};
template <typename C>
std::string tprint(int C::*){ return "member Integer";};