Hooked
Hooked

Reputation: 88148

How to conditionally compile a templated function over the return type

If I template a function in C++ on the return type:

template<class T> T foo(int x) { };

I can use explicit template specialization to create a double instance:

template<> double foo<double>(int x) { };

I tried to use forward declaration to create an instance of an undefined struct:

struct bar;
template<> bar foo<bar>(int x) { }

This fails with error: return type ‘struct bar’ is incomplete. I thought this would be allowed, even after reading the accepted answer on When to use forward declaration? since, until I create an instance of foo<bar>, the explicit templated code is never created. Clearly this is not the case (why not?).

Is it possible to have code for functions whose type might not exist at compile time, and only compile the code if the particular explicit specialization is instanced? The motivation for this is an "overloaded" struct reader, where the overload operations are procedurally generated before the compile (via a script).

Upvotes: 1

Views: 106

Answers (2)

When you define an specialization of a function you are defining the function, not a function template. The rules at this point are exactly the same as for any regular function and because you are using the type in a way that needs a complete type, the lack of a definition for bar makes your program ill-formed.

(The lack of a return statement also makes the program ill-formed...)

Upvotes: 2

mfontanini
mfontanini

Reputation: 21900

You can do that, if you don't provide the body of the foo function:

// some header file, probably
struct bar;
template<> bar foo<bar>(int x);

// somewhere else:

struct bar { 
    //blabla 
};

// the actual implementation
template<> bar foo<bar>(int x) {
    // do something
}

The forward declaration works only if you don't actually require the definition of bar. In your foo function's body, you need to know the size of that struct, that's why your code didn't work.

Upvotes: 2

Related Questions