Domanda

I have a class template with three constructors and one of them is function template.

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;
};

From my application I need to distinguish between reference type/value, pointer and array and perform specific operation. Hence I decided to have to different constructors.

I am trying to invoke the constructor in the following manner:

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 );

The problem is if the constructor with the pointer is defined the array constructor is never invoked. However, if I comment that one out it prints the array as it should.

Output:

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

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

So syntactically it is possible and it is correct deducing the the array size N.

Obviously I am confusing the compiler when the array constructor is present. So instead of letting the compiler automatically deduce I tried to specify the template parameter for the array constructor to only find out unlike the regular function, template parameters cannot be specifically specified.

I thought of introducing a dummy parameter in the array constructor to differentiate the overloading but it doesn't seem nice.

Is there any other way to resolve this? Any clue appreciated.

È stato utile?

Soluzione

Make your pointer constructor parameter to T*& qValue.

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

By making it a reference to a pointer, array-to-pointer decay is prevented and the array constructor is chosen.

Also, I don't see how your code compiles, I see many errors:

Your template constructor has a parameter class T, this conflicts with the class T of the class template:

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

This needs to be changed to something else than class T, for example class U:

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

Your constructors also take a non-const lvalue reference, non const reference cannot bind to temporaries, which you are passing in the constructor call, i.e. std::string("mIntArray"). You need to change it to const std::string& or take it by value. Also your member std::string& mName; is a reference, you should remove the & there.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top