模板构造函数重载问题

时间:2013-03-04 03:07:11

标签: c++ templates function-templates constructor-overloading

我有一个包含三个构造函数的类模板,其中一个是函数模板。

template<class T>
class TemplateOverLoading
{
public:
    TemplateOverLoading(void){};
    ~TemplateOverLoading(void){};
    //constructor that take reference
    TemplateOverLoading(std::string& qName, T& qValue )
        :   mName(qName),
            mValue( &qValue)
    {
        std::cout << "Reference -> "<< *mValue <<"\n";
    }

    //Template constructor that takes array
    template<class T, int N>
    TemplateOverLoading(std::string& qName, T (&t)[N])
        :   mName(qName),
            mValue(t)
    {
        std::cout << "Array ->\n";
        for(int i = 0; i < N; i++)
            std::cout<< mValue[i];
        std::cout << std::endl;
    }

    //Other constructor that take pointer
    TemplateOverLoading(std::string& qName, T* qValue )
        :   mName(qName),
            mValue( qValue)
    {
        std::cout << "Pointer "<< *mValue <<"\n";
    }
private:
    T*               mValue;
    //T*              mValueArray;
    std::string&    mName;
};

从我的应用程序中我需要区分引用类型/值,指针和数组并执行特定操作。因此我决定不同的建设者。

我试图以下列方式调用构造函数:

int init(10);
int intArray[10] = {0,1,2,3,4,5,6,7,8,9};
TemplateOverLoading<int> mInt(std::string("mInt"), init);    
TemplateOverLoading<int> mIntArray( std::string("mIntArray"), intArray );

问题是如果定义了带指针的构造函数,则永远不会调用数组构造函数。但是,如果我发表评论,它会打印出应该的数组。

输出:

(when pointer constructor is present)
Reference -> 10
Pointer 0

(when pointer constructor is not present)
Reference -> 10
Array ->
0123456789

从语法上讲,它是可能的,并且正确推导出数组大小N。

显然,当数组构造函数存在时,我会混淆编译器。因此,我没有让编译器自动推断,而是试图为数组构造函数指定模板参数,以便只查找与常规函数不同的模板参数,不能具体指定模板参数。

我想在数组构造函数中引入一个虚拟参数来区分重载但是看起来不太好。

还有其他方法可以解决这个问题吗?有任何线索赞赏。

1 个答案:

答案 0 :(得分:1)

将指针构造函数参数设为T*& qValue

TemplateOverLoading(std::string& qName, T*& qValue )
    :   mName(qName),
        mValue( qValue)
{
    std::cout << "Pointer "<< *mValue <<"\n";
}

通过使其成为对指针的引用,可以防止数组到指针的衰减,并选择数组构造函数。

另外,我没看到你的代码是如何编译的,我看到很多错误:

您的模板构造函数有一个参数class T,这与类模板的class T冲突:

template<class T, int N>
    TemplateOverLoading(std::string& qName, T (&t)[N])

这需要更改为class T之外的其他内容,例如class U

template<class U, int N>
        TemplateOverLoading(std::string& qName, U (&t)[N])

你的构造函数也采用非const 左值引用,非const引用不能绑定到你在构造函数调用中传递的临时值,即std::string("mIntArray")。您需要将其更改为const std::string&或按值取值。您的会员std::string& mName;也是一个参考,您应该删除那里的&