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?

Michi Henning
  • 198
  • 1
  • 7

2 Answers2

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.

Stuart Golodetz
  • 20,238
  • 4
  • 51
  • 80
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...)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Ah, thanks for that! I know about the `static` and `inline`. I just reduced this to something as simple as possible. The `clone_` function arises in the context of pimpls and incomplete types. See Alan Griffith's `Grin_ptr`: [link](http://accu.org/var/uploads/journals/overload72-FINAL.pdf). – Michi Henning Oct 07 '12 at 23:58