dunadar
dunadar

Reputation: 1785

Specialization of casting operator to template argument

I can't find this question answered in any other place, so I finally decided to ask. I have a C++ templated class that includes a casting operator to the type of one of the arguments:

template <class E, class B>
class bar {
    private:
        B innerVal_;
    [...]
    public:
        /* Casting to the type of the 2nd template argument */
        operator B() const { return innerVal_; }; // default implementation provided
};

However, I need to provide a specialization of this casting operator for some specific template arguments, for instance:

template<>
bar<concreteType,int>::operator int() // <-- whoops, error!
{ [...] } 

The thing is that, no matter how I specify the syntax of the casting operator, gcc consistently returns me an error referred to the declaration of the function. The most common one is:

error: template-id ‘operator int<>’ for ‘bar< concreteType, int>::operator int()’ does not match any template declaration.

Which I got with these lines:

I also played around with the "typename" keyword, with template brackets, and made some other desperate attempts. All of them result in bizarre errors --that I'm not going even to paste here.

Am I losing some obvious detail? Do you have any hint/pointer for me? Any help will be useful.

Upvotes: 2

Views: 1230

Answers (1)

Mooing Duck
Mooing Duck

Reputation: 66922

In C++ you cannot specialize a member function on the template parameters of the class. So here's the workaround:

template <class E, class B>
class bar_base {  //base class with 99% of the implementation
    private:
        B innerVal_;
    public:
    [...] //most of your members here
};
template <class E, class B>
class bar : public bar_base<E,B> { //normal instantiation
public:
    [...] //constructors only
    /* Casting to the type of the 2nd template argument */
    operator B() const { return innerVal_; }; // default implementation provided
};
template <class E>
class bar<E,int> : public bar_base<E,int> { //E,int specialization
public:
    [...] //constructors only
    operator int() const { [...]};
};

or, much simpler now that I think on it:

private:
    template<class T>
    T convert_to() {return innerVal_; }
    template<>
    int convert_to<int>() {return innerVal_; }
public:
    operator B() const { return convert_to<B>(); };

Upvotes: 3

Related Questions