我试图将类成员的类型作为模板参数传递。为此,我使用以下代码:

class C
{
public:
    int a;
};
class B
{
public:
    template<typename _T> void Test() {}
    // Specialize for int for Test testing purposes.
    template<> void Test<int>() { printf("Success!\n"); }
};

//Later:
B b;
C c;
b.Test<decltype(c.a)>();


这给了我以下错误:


  错误C2662:'void B :: Test(void)':无法转换'this'指针
  从“ C”转换为“ B&”原因:无法从“ C”转换为“ B”
  需要第二个用户定义的转换运算符或构造函数


但是,如果我使用以下代码,它确实可以工作:

decltype(c.a) d;
b.Test<decltype(d)>();


如果我直接使用类成员,为什么它不起作用?
我正在使用Visual Studio 2012。

最佳答案

7.1.6.2(4)


  对于表达式e,用decltype(e)表示的类型定义如下:
  
  
  如果e是未括号的id表达式或未括号的类成员访问权限(5.2.5),则decltype(e)e命名的实体的类型。
  如果没有这样的实体,或者e命名一组重载函数,则程序格式错误;
  否则,如果e是xvalue,则decltype(e)T&&,其中Te的类型;否则,
  否则,如果e是左值,则decltype(e)T&,其中Te的类型;否则,
  否则,decltype(e)e的类型。
  


VS2012似乎忘记了(或从未告诉过)我加粗的部分,即e是未括号化的类成员访问的情况。因此,它可能会退回到e是左值的规则,因此对于VS2012,decltype(c.a)表示int&(对int的引用)。

您的示例还包含以_开头的标识符和未定义行为的大写字母(_T)。见What are the rules about using an underscore in a C++ identifier?

关于c++ - 类成员的Decltype作为模板参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25248680/

10-11 22:33
查看更多