源代码https://github.com/kennywakeland/Decltype-Bug/blob/master/main.cpp
测试编译https://coliru.stacked-crooked.com/a/443f03625728f00e
此代码用于使用宏测试setter和getter。我想传递变量名称。 decltype没有将正确的类型返回给HTestSet。知道为什么它没有返回正确的值类型?
编译器错误g ++ -std = c ++ 11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:26:72: error: no matching function for call to 'HTestSet(TestClass&, void (BaseClass::*)(int), int&)'
if(HTestSet(OBGEC_ON, &decltype(OBGEC_ON)::SET_CALL, test_vall_stor)){
^
main.cpp:18:1: note: in expansion of macro 'H_TEST_VALUE_GET_SET'
H_TEST_VALUE_GET_SET(H_GET_VALUE(OBGEC_ON, VAL_NAME), \
^~~~~~~~~~~~~~~~~~~~
main.cpp:92:5: note: in expansion of macro 'H_TEST_VALUE'
H_TEST_VALUE(woo, Green, 3);
^~~~~~~~~~~~
这不是一个错误(据我所知),与decltype
无关。问题是setGreen
是BaseClass
的非虚拟成员函数,因为你没有在TestClass
中重新声明这样的函数,所以类型:
&TestClass::setGreen
是:
void (BaseClass::*)(int)
...因此,您在HTestSet
的模板实例化中存在模板参数冲突。
我没有找到比[expr.unary.op#3]更好的标准报价:
一元
&
运算符的结果是指向其操作数的指针。操作数应为左值或限定ID。如果操作数是一个qualified-id,命名类型为m
的某个类C
的非静态或变体成员T
,则结果类型为“指向C
类T
类的成员的指针”,并且是指定C::m
的prvalue。 [...]struct A { int i; }; struct B : A { }; ... &B::i ... // has type int A::*
在f
开头使用main
只能起作用,因为在这种情况下void (BaseClass::*)(int)
可以隐式转换为void (TestClass::*)(int)
,[conv.mem#2]:
类型为“指向cv T类型的B的成员的指针”的prvalue,其中B是类类型,可以转换为类型为“指向cv T类型的D的成员的指针”的prvalue,其中D是派生类( B. [...]由于结果的类型为“指向cv T类型D的成员的指针”,因此通过它与D对象的间接是有效的。结果与使用D的B子对象通过指向B成员的指针相同。