当我用T
手动替换char *
时,以下示例正常工作,但为什么不能正常工作:
template <typename T>
class A{
public:
A(const T _t) { }
};
int main(){
const char * c = "asdf";
A<char *> a(c);
}
使用gcc编译时,出现此错误:
test.cpp: In function 'int main()':
test.cpp:10: error: invalid conversion from 'const char*' to 'char*'
test.cpp:10: error: initializing argument 1 of 'A<T>::A(T) [with T = char*]'
答案 0 :(得分:10)
用T
替换char*
会给char指定const
指针,而c
则指向const char
的指针。
解决方案是通过const引用按值和类类型获取指针和整数类型。如果可以,请使用Boost Call Traits来解决这些问题。
答案 1 :(得分:2)
我想这是因为你的函数需要const (char *)
(因为T是char *
),即你无法更改它指向的地址,而const char *
代表(const char) *
},即你不能改变指针指向的位置的值。
答案 2 :(得分:2)
这里发生的事情是编译器知道您的模板是用T = char*
实例化的,并且首先尝试查看您提供的值(c
)是否为char*
(它在检查其常数之前,它不是; const char*
)。
因此你需要:
const_cast
值c
A<const char *> a(c);
const
说明符
醇>
这些中最好的是#3。这将失去你我所假设的你需要的“保证”:用于初始化A类对象的值是不变的。要再次实现此目的,您必须使用type traits和template constraints的某些实现来确保在T不是const
类型时无法实例化模板。
答案 3 :(得分:1)
如果在c分配之前消除了const,程序将编译。
发生的事情是构造函数不一定是实例的const版本。 const告诉构造函数你不能改变T _t中的数据,这实际上并不是构造函数范围内的const对象......这是一个非常微妙但重要的区别。
答案 4 :(得分:1)
如果你制作了构造函数A(const char* _t)
,那么你就会有效地A( (const char) *t)
。也就是说,指向const char的指针。但是当您指定char*
作为模板参数时,您将获得有效的A( const (char *t))
,或者指向char的const指针。
换句话说,我认为您在文章A Midsummer Night's Madness中讨论的问题相同,除了使用模板参数而不是typedef。
答案 5 :(得分:0)
尝试转换为const T&amp ;.此外,在这些情况下,您应该让编译器自动推导出模板参数,而不是指定它。