tags:

views:

200

answers:

5

Hello!

Is there any way to achieve the specified behaviour? If there is some trick or this could be done using traits or enable_if, please let me know.

template <typename T> struct Functional {

   T operator()() const {

      T a(5);

                // I want this statement to be tranformed into
                // plain 'return;' in case T = void
      return a; // <---
   }
};

int main() {

   Functional<int> a;
   a();

   Functional<void> b;
   b(); // <--- Compilation error here
}
+23  A: 

Just specialize for void:

template <typename T> struct Functional {
   T operator()() const {
      T a(5);
      return a;
   }
};
template <> struct Functional<void> {
   void operator()() const {
   }
};
David Rodríguez - dribeas
+3  A: 
ULysses
+5  A: 

This should work

template <> struct Functional<void> //specialized for 'void'
{
   void operator()() const {

       //do something

      return ; //optional
   }
};

EDIT:

You can also write (Simpler approach)

T operator()() const {

   return T(5); // static_cast<> not even required
}
Prasoon Saurav
A: 

There are bigger problems with this code than first appears. For example, if you were to forward the return value of Functional to another function, then you can't just spec Functional for void- the whole lot has to be specced for void, since if you have a function that takes void, you can't pass it a void expression. And of course, you can't create variables with void, and suchlike. Overall, it's just easier to say that void is illegal than try to deal with it.

There are other answers which already have the explicit specialization answer.

DeadMG
+8  A: 

Just say the following. It works perfectly well with T being void and is equivalent to the code you have shown

T operator()() const {
  return static_cast<T>(5);
}
Johannes Schaub - litb
+1: I don't think most people know that you can `return` an expression of type `void` from a function with a return type of `void`.
James McNellis
@Johannes : Is the `static_cast<>` even required? `T operator()() const {return T(t) }` can be used instead.
Prasoon Saurav
@Prasoon Saurav: An expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration “T t(e);” is well-formed, for some invented temporary variable t (8.5). So both are same. Of course you can't do (void v(5)) which is why I guess the standard has an explicit note about conversion to void (under static_cast). I like the static_cast because of it's explicitness
Chubsdad
@Chubsdad : No my point is although static_cast<> is good, it is not required. :)
Prasoon Saurav
@Prasoon many people regard C-style casts as bad. And although I'm not of that fraction (I believe C-Style casts are not nearly as bad as some people claim), I think in generic code one should really use C++ style casts since one won'T know what type `T` is going to be.
Johannes Schaub - litb