The random rantings of a concerned programmer.

Calling a templated member function of a typedef’d template class

July 11th, 2011 | Category: Random

C++ is insane.

Assume you have a templated Object:

template 
struct Object {
        template  void func(){};
};

And you want to wrap up the instance in a Proxy object:

template 
struct Proxy {
        typedef Object WrappedType;
        WrappedType obj;

        static void Func() {
                Proxy *self = new Proxy;
                self->obj.func();
        }
};

Pretty straightforward, but when you actually try to invoke Proxy::Func on an arbitrary T using g++

struct Foo {};

int main() {
        Proxy::Func();
        return 0;
}

g++ shits itself completely:

$ g++ test1.cpp
test1.cpp: In static member function ‘static void Proxy::Func()’:
test1.cpp:13: error: ‘Foo’ was not declared in this scope
test1.cpp:13: error: expected primary-expression before ‘)’ token
$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

Fucking fantastic.

Some tinkering reveals that the compiler is getting confused as to what the fuck obj.func is somewhere. The following implementation of Func works fine (but defeats the point of using templates) --

   static void Func() {
                Proxy *self = new Proxy;
                Object bar = self->obj;
                bar.func();
        }

I searched for awhile and turned up jack diddly squat, then a co-worker informed me the fix is to use the following:

   static void Func() {
                Proxy *self = new Proxy;
                self->obj.template func();
        }

I don't know what the fuck this instance.template function<..>() bullshit is, but apparently MSVC implicitly puts it in there for you. I've certainly never seen it before and it's completely orthogonal to any fix I would have assumed.

tl;dr C++ is a clusterfuck.


EDIT: A stack overflow post which contains a reference to the C++03 standard (14.2/4) in the answers. fml.

4 comments