2010-05-12 54 views
3

下面的例子是工作时我manualy更换T wirh char *,但为什么不工作,因为它是:C++:结合常数与模板参数

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

尝试转换为常量T &。此外,在这些情况下,您应该让编译器自动推断模板参数,而不是指定它。

1

如果在c的赋值之前消除常量,程序将编译。

发生什么事情是构造函数不一定需要一个实例的const版本。 const告诉构造函数你不能改变T_t中的数据,这实际上并不是构造函数范围内的一个const对象......这是一个非常微妙而重要的区别。

10

Tchar*替代给出指向char的const指针,而c被声明为指向const char的指针。

一个解决方案是通过const引用,通过值和类类型来获取指针和整型。如果可以,请使用Boost Call Traits为您解决这些类型的问题。

2

我想这是因为你的函数需要const (char *)(因为T是char *),即你不能改变它指向的地址,而const char *代表(const char) *,即你不能在指针位置更改值指着。

2

这里发生的是,编译器知道你的模板实例与T = char*,并首先尝试,看看是否值时,您提供(c)是char*(它不是,它是一个const char*检查它的恒定性。

因此,你需要:

  1. const_castc
  2. 指定A<const char *> a(c);
  3. 从A的构造函数的声明中删除const

这些中最好的做是#3。这会让你失去你所需要的“保证”:用于初始化A类对象的值是不变的。为了再次实现这一点,您将不得不使用type traitstemplate constraints的一些实现来确保当T不是const类型时不能实例化模板。

+0

除非您的要求包含未定义的行为,否则不要将'const_cast'指针指向'const'数据。 – 2010-05-13 10:57:18

1

如果你使你的构造函数A(const char* _t),你得到有效A((const char) *t)。也就是说,一个指向const char的指针。但是当你指定char*作为模板参数时,你会有效地得到A(const (char *t)),或者是一个指向char的常量指针。

换句话说,我认为你有A Midsummer Night's Madness文章中讨论的相同问题,除了使用模板参数而不是typedefs。