模板类构造函数的专业化

时间:2014-08-27 13:13:23

标签: c++ templates template-specialization partial-specialization

我是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");
}

输出

模板

模板

2 个答案:

答案 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&)