3
votes

This question might overlap with this one: C++ explicit template specialization of templated constructor of templated class . However, I didn't find a solution in that thread.

I have a templated class with templated constructor:

template<typename First, typename ... Rest> class var {
    public:
        template<typename T> var(T& t) {
            std::cout << "general" << std::endl;
        }
};

But in case this class is instantiated with an object of the same class as parameter (i.e., we'd like to call the copy- (or move-) constructor) something specific should be done. So I tried the following:

template<typename First, typename ... Rest> template<> 
var<First, Rest...>::var(var<First, Rest...>& v) {
    std::cout << "copy" << std::endl;
}

When trying to compile this with g++ 4.6 I get error: invalid explicit specialization before ‘>’ token error: enclosing class templates are not explicitly specialized confused by earlier errors, bailing out

I see the problem, I would have to say explicitly for which class I would like to specialize the constructor...

However, I hope it became clear what I want to do. Any ideas how?

2

2 Answers

1
votes

A template constructor is no copy constructor:

template<typename First, typename ... Rest> class var {
    public:
    var() {};
    var(const var& v) {
        std::cout << "copy" << std::endl;
    }
    template<typename T>
    var(const T& t) {
        std::cout << "general" << std::endl;
    }
};

int main()
{
    var<int> i0;
    var<int> i1(i0);
    var<int> i2("Hello");
}

Gives

copy
general

Note: Added some const

Your attempt to specialize a non copy constructor as copy constructor is failing.

12.8:

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).

0
votes

You cannot specialize templated method without fully specializing the class. It is prohibited by C++ standard.

Typical workaround for that is function/method overloading as Dieter Lücking showed in his answer.

Also answered here