[英]Decltype on class member as template argument
我试图将类成员的类型作为模板参数传递。 为此,我使用以下代码:
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。
我认为在类内部定义特殊化是不合法的,它必须在名称空间级别(g ++无法编译您的代码, error: explicit specialization in non-namespace scope 'class B'
)。 尝试在类外定义模板,
template<> void B::Test<int>() { printf("Success!\n"); }
这段代码对我来说非常好(在g ++上),如果对您不起作用,则可能是VS问题。
#include <iostream>
using namespace std;
class C
{
public:
int a;
};
class B
{
public:
template<typename _T>
void Test() {}
// Specialize for int for Test testing purposes.
};
template<> void B::Test<int>() { cout << "Success!\n"; }
int main()
{
B b;
C c;
b.Test<decltype(c.a)>();
}
7.1.6.2(4)
对于表达式
e
,由decltype(e)
表示的类型定义如下:
- 如果
e
是未括号化的id表达式 或未括号化的类成员访问权限 (5.2.5),则decltype(e)
是e
命名的实体的类型。- 如果没有这样的实体,或者如果
e
命名了一组重载函数,则程序格式错误;- 否则,如果
e
为x值,则decltype(e)
为T&&
,其中T
为e
的类型;- 否则,如果
e
为左值,则decltype(e)
为T&
,其中T
为e
的类型;- 否则,
decltype(e)
是的类型e
。
VS2012似乎忘记了(或从未告诉过)我加粗的部分,其中e
是非括号类成员访问。 因此,它可能会退回到当e
为左值时的规则,因此对于VS2012, decltype(ca)
表示int&
(对int
的引用)。
您的示例还包含以_
开头的标识符和未定义行为的大写字母( _T
)。 请参阅有关在C ++标识符中使用下划线的规则?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.