2

I'm getting a truly bizarre error message from gcc 4.6 about a template member function. Here is a minimal example:

template<typename T>
class Pimpl
{
public:
    Pimpl(const Pimpl&) {}

private:
    T* clone_(const T*);
};

template<typename T>
template<typename P>
T*
Pimpl<T>::clone_(const T*)
{
    return new P(static_cast<const P&>(*p));
}

Here is the error:

$ c++ -c y.cpp
y.cpp:14:1: error: prototype for ‘T* Pimpl<T>::clone_(const T*)’ does not match any in  class ‘Pimpl<T>’
y.cpp:8:8: error: candidate is: T* Pimpl<T>::clone_(const T*)

Note that the non-matching prototype is exactly the same as the candidate one.

What gives?

4

2 に答える 2

3

They're different because of the template <typename P>. The Comeau error message (as generated at http://www.comeaucomputing.com/tryitout) highlights the problem you're having:

error: template nesting depth does not match the previous declaration of function "Pimpl<T>::clone_"

It's worth mentioning in general that:

(a) The Comeau compiler is known for producing particularly good error messages.

(b) Compiling with multiple compilers will often given you insights that you might not have had otherwise.

于 2012-10-07T23:40:55.313 に答える
2

If you want a member template, you have to declare it as such:

template <typename T>
class Pimpl
{
    // ...

    template <typename P>
    static P * clone(T const * p)
    {
        return new P(static_cast<P const &>(*p));
    }
};

I also made the member template static because it doesn't seem to depend on an object instance, and I defined it inline, because you have to supply the template definition in the header anyway, and I fixed the return type. (But I fail to see how the templated clone function makes any sense...)

于 2012-10-07T23:41:16.860 に答える