我使用模板,我对使用模板参数调用函数感到恼火。例如:
我有一个模板结构
template<typename T>
struct telement {
typedef {
T element;
float some_value;
} type;
};
telement<float>::type theElement;
我有一个功能:
template<typename T>
float do_some_stuff( const typename telement<T>::type& x) {
// ...
}
不可思议的是,当我打电话时,g ++会抱怨
do_some_stuff( theElement );
我必须致电:
do_some_stuff<float>( theElement );
每次调用函数时都可以避免模板规范吗?我认为编译器应该自动找出类型...
答案 0 :(得分:4)
这是不可导出的背景之一。编译器无法推断出模板参数T
。
自己提出这个问题:当你写这个时,
do_some_stuff( theElement );
您认为应该为T
安排什么类型的参数?
您可能认为T=float
?嗯,这只是一种可能性。 可以存在类模板的特化:
//the compiler cannot assume that such specialization doesn't exist!
template<>
struct telement<someType>
{
typedef {
float element;
float some_value;
} type;
};
然后即使在这种情况下,嵌套类型telement<someType>::type
也与telement<float>::type
相同。你看到了歧义吗? T
和嵌套type
之间没有一对一的关系。实际上可能存在多种关系。可能有许多T
嵌套类型相同,相同。
所以给定嵌套类型,编译器如何决定模板参数?它不能
有关SO的几个主题可以解释类似情况,请参阅:
解决方案是,只需将函数模板写为:
template<typename T>
float do_some_stuff( const T& x) {
// ...
}
毕竟,在参数中写telement<T>::type
是什么意思?
答案 1 :(得分:2)
以下是使用它的方法:
#include <iostream>
template<typename T>
struct telement {
typedef struct {
typedef T t_element_type;
typedef float t_value_type;
t_element_type element;
t_value_type some_value;
} type;
};
template<typename T>
float imp_do_some_stuff(const typename telement<T>::type& x) {
return x.some_value;
}
template<typename T>
float do_some_stuff(const T& x) {
return imp_do_some_stuff<typename T::t_element_type>(x);
}
int main() {
telement<float>::type theElement;
do_some_stuff(theElement);
return 0;
}