2

Consider a function

template <typename Ret>
Ret function(...) {
    Ret a;
    // . . . do something with a
    return a;
}

If I call this as

function<void>();

the compiler says

error: variable or field 'a' declared void

error: return-statement with a value, in function returning 'void' [-fpermissive]

How do I enforce a check on in this function, for instance

template <typename Ret>
Ret function(...) {
    // if (Ret is void) return;
    Ret a;
    // . . . do something with a
    return a;
}

I know C++11 has std::is_void and std::is_same

bool same = std::is_same<Ret, void>::value;

Anything in C++03 ? Thanks in advance.

Community
  • 1
  • 1
Shreevardhan
  • 12,233
  • 3
  • 36
  • 50
  • 2
    Easiest would be to provide a template specialization for `void`. You'd need to do similar stuff even in C++11, since an early `return` doesn't stop the compiler from enforcing type rules on the rest of the function body. – Sneftel Jul 16 '15 at 13:34

2 Answers2

4

You can just specialize, or write your own is_same, that's pretty easy, or of course you can use not-standard libraries (for example boost).

Specialization

template<typename Ret>
Ret function(...)
{
   Ret a;
   // ...
   return a;
}

template<>
void function<void>(...)
{
}

Own

template<typename T, typename U>
struct is_same
{
   static const bool value = false;
};

template<typename T>
struct is_same<T, T>
{
   static const bool value = true;
};

BTW with is_same it's not so simple, that you think. You also need specialization, or overloading

template<typename Ret>
typename enable_if<!is_same<Ret, void>::value, Ret>::type
function(...)
{
   Ret a;
   // ...
   return a;
}

template<typename Ret>
typename enable_if<is_same<Ret, void>::value, Ret>::type
function(...)
{
}

So, just specialization is more simple.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
1

A runtime if would not be enough, all instantiations of a template must be compilable. In your case, a specialisation might be the best course of action:

template <typename Ret>
Ret function(...) {
    Ret a;
    // . . . do something with a
    return a;
}

template <>
void function<void>(...) {
    return;
}

Also, there is boost::is_same available for C++03.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455