我是C ++模板的新手。 谁能解释为什么我的专用构造函数永远不会被执行。 当我删除const和reference运算符时它可以工作。
#include<iostream>
#include<string>
using namespace std;
template<typename T>
class CData
{
public:
CData(const T&);
CData(const char*&);
private:
T m_Data;
};
template<typename T>
CData<T>::CData(const T& Val)
{
cout << "Template" << endl;
m_Data = Val;
}
template<>
CData<char*>::CData(const char* &Str)
{
cout << "Char*" << endl;
m_Data = new char[strlen(Str) + 1];
strcpy(m_Data, Str);
}
void main()
{
CData<int> obj1(10);
CData<char*> obj2("Hello");
}
输出
模板
模板
答案 0 :(得分:5)
因为您无法将"Hello"
绑定到const char*&
。
评论中添加的信息dyp非常有趣:
字符串文字是一个数组左值,可以转换为指针prvalue。指针prvalue不能绑定到const const *&amp;
之类的非const左值引用
这意味着您可以通过将const char*&
替换为const char* const&
,或者在c ++ 11中替换const char* &&
来实际使其工作,但不确定这在您的用例中是否真的很聪明
答案 1 :(得分:2)
更新我搞错了,完全重写了答案。
首先,这个构造函数
template<>
CData<char*>::CData(const char* &Str)
不是CData(const T&)
的特化,因为这里的Str
参数是指向const char
的非const引用。因此,它是非模板化构造函数CData(const char*&)
的定义。
其次,"Hello"
的类型为&#34;数组为n const char
&#34; (参见What is the type of string literals in C and C++?)因此无法将其转换为非const引用。这就是为什么&#34;模板&#34;构造函数被调用。
正确的专业化是
template<>
CData<char*>::CData(char* const& Str)
也就是说,它接受对char*
的const引用。
之后你应该删除CData(const char*&)
,除非你需要这个代码来编译:
const char* foo = "foo";
CData<int> obj2(foo);
所以这是代码:
template<typename T>
class CData
{
public:
CData(const T&);
private:
T m_Data;
};
template<typename T>
CData<T>::CData(const T& Val)
{
....
}
template<>
CData<char*>::CData(char* const& Str)
{
....
}
// warning: deprecated conversion from string constant to 'char*'
CData<char*> obj2("Hello"); // calls CData(char* const&)
修正上述警告的正确方法是添加另一项专业化:
template<>
CData<const char*>::CData(const char* const& Str)
{
...
}
CData<const char*> obj2("Hello"); // calls CData(const char* const&)