C++ 如果使用typedef,则无法推断模板参数
我有一个“无法推断T的模板参数”错误的问题 这是我的班级:C++ 如果使用typedef,则无法推断模板参数,c++,C++,我有一个“无法推断T的模板参数”错误的问题 这是我的班级: class PropertyAccess { public: template <typename TClass, typename TType> struct SetterPointer { typedef void (TClass::*Type)(const TType&); }; template <typename TClass, typename TType>
class PropertyAccess
{
public:
template <typename TClass, typename TType>
struct SetterPointer { typedef void (TClass::*Type)(const TType&); };
template <typename TClass, typename TType>
struct GetterPointer { typedef TType(TClass::*Type)(); };
template <typename TClass, typename TType>
void Assign(
TClass* object,
typename SetterPointer<TClass, TType>::Type setter,
typename GetterPointer<TClass, TType>::Type getter)
{
...
}
}
类属性访问
{
公众:
模板
结构SetterPointer{typedef void(TClass::*Type)(const TType&);};
模板
结构GetterPointer{typedef TType(TClass::*Type)(;};
模板
无效转让(
TClass*对象,
typename setterInter::类型setter,
类型名称GetterPointer::类型getter)
{
...
}
}
下面是我如何使用它:
class Test
{
public:
int a;
void Set(const int& v) { a = v; }
int Get() { return a; }
};
void main
{
Test test;
PropertyAccess property;
property.Assign(&test, &Test::Set, &Test::Get); <---here is compile error
}
类测试
{
公众:
INTA;
空集(常数int&v){a=v;}
int Get(){返回一个;}
};
真空总管
{
试验;
财产取得财产;
property.Assign(&test,&test::Set,&test::Get);C++无法从其嵌套类型推断封闭类型。这是一个非推断上下文的示例
一个最简单的例子是
struct S { typedef int T; };
template <typename C> void foo(typename C::T i) {}
int main() {
int x = 0;
foo(x); // ERROR: non-deduced context
}
C++无法从嵌套类型推断封闭类型。这是未推断上下文的一个示例
一个最简单的例子是
struct S { typedef int T; };
template <typename C> void foo(typename C::T i) {}
int main() {
int x = 0;
foo(x); // ERROR: non-deduced context
}
非常全面的回答,谢谢。有一件事我仍然不明白:为什么它对setter正确工作?请注意,我必须更改only getter定义以使代码正确编译。@majakthecoder:它实际上不“工作”同样,编译器要做的是推导Assign
的两个模板参数:parameterTClass
和parameterTType
。编译器检查Assign
的第一个参数(object
)这立即允许它推断出TClass==Test
。因此,TClass
参数现在得到处理。编译器继续执行Assign
-setter
-的第二个参数,发现它没有用,因为上下文是不可推断的。编译器只是跳过它。然后编译器继续执行t第三个参数TType(TClass::*getter)(
,并从中推断出TClass==Test
(与前面的推断一致)并且TType==int
。现在查看所有参数。所有模板参数的推导和推导都是一致的。因此,代码可以编译。因此,非推导上下文不是错误。推导算法只会忽略非推导上下文中的参数。如果您的所有模板参数都将由其他人推导ans(通过其他函数参数),则您仍然可以。但是,如果您最终得到的模板参数无法从任何函数参数中推导出来,代码将无法编译。@majakthecoder:您可以使用C++11的“模板类型定义”(又名别名模板)功能。使用SetterPointer=void(TClass::*)的模板(const TType&);
非常全面的答案,谢谢。有一件事我仍然不明白:为什么它对setter正确工作?请注意,我必须只更改getter定义才能使代码正确编译。@majakthecode:它实际上不“工作”同样,编译器要做的是推导Assign
的两个模板参数:parameterTClass
和parameterTType
。编译器检查Assign
的第一个参数(object
)这立即允许它推断出TClass==Test
。因此,TClass
参数现在得到处理。编译器继续执行Assign
-setter
-的第二个参数,发现它没有用,因为上下文是不可推断的。编译器只是跳过它。然后编译器继续执行t第三个参数TType(TClass::*getter)(
,并从中推断出TClass==Test
(与前面的推断一致)并且TType==int
。现在查看所有参数。所有模板参数的推导和推导都是一致的。因此,代码可以编译。因此,非推导上下文不是错误。推导算法只会忽略非推导上下文中的参数。如果您的所有模板参数都将由其他人推导ans(通过其他函数参数),则您仍然可以。但是,如果您最终得到的模板参数无法从任何函数参数中推导出来,代码将无法编译。@majakthecoder:您可以使用C++11的“模板类型定义”(又名别名模板)功能。使用SetterPointer=void(TClass::*)的模板(const TType&);
一个有趣的问题。问题的一部分是SetterPointer
和GetterPointer
试图成为元函数,但您并不是用两个参数“调用”它们。如果我添加这个重载,调用元函数,它会起作用:template void Assign(TClass*object,T1 setter,T2 getter){Assign*getter())>(object,setter,getter);}就是这么说的“如果我想用一个类和两个类型分配
,请查找getter的结果类型并使用它。有趣的问题。问题的一部分是,SetterPointer
和GetterPointer
试图成为元函数,但您不是在“调用”如果我添加这个重载,调用元函数,它会工作:模板void Assign(TClass*object,T1 setter,T2 getter){Assign*getter())>(object,setter,getter);}也就是说“如果我想用一个类和两个类型分配,请查找getter的结果类型并使用它。
struct S { typedef int T; };
template <typename C> void foo(typename C::T i) {}
int main() {
int x = 0;
foo(x); // ERROR: non-deduced context
}
template <typename X> struct S { typedef X T; };
template <typename X> void foo(typename S<X>::T i) {}
int main() {
int x = 0;
foo(x); // ERROR: non-deduced context
}
class PropertyAccess
{
public:
template <typename TClass, typename TType>
using SetterPointer = void (TClass::*)(const TType&);
template <typename TClass, typename TType>
using GetterPointer = TType(TClass::*)();
template <typename TClass, typename TType>
void Assign(
TClass* object,
SetterPointer<TClass, TType> setter,
GetterPointer<TClass, TType> getter)
{
...
}
};