I have a template class that needs to perform some operation before calling a function whose parameters and return type are common.
This is the method:
template <typename ReturnType, typename ...Args> ReturnType function (Args ...args) {
Of course, it compiles correctly when ReturnType not void . When I use it in this context:
function<void>(firstArg, secondArg);
The compiler is responsible
error: return-statement with a value, in function returning 'void' [-fpermissive]
pointing to the line marked [1].
Is there any solution other than passing -fpermissive compiler? I would prefer to have a unique method because I found a possible solution to create different versions using enable_if and is_same .
Thanks in advance.
- Update -
This is a complete example. I should have said that our functions are really cool methods.
#include <type_traits> #include <iostream> class Caller { public: Caller() {} template <typename ReturnType, typename ...Arguments> ReturnType call(Arguments ... args) { prepare(); ReturnType rv = callImpl<ReturnType>(args...); done(); return rv; } private: void prepare() { std::cout << "Prepare\n"; } void done() { std::cout << "Done\n"; } template <typename ReturnType, typename ...Arguments> typename std::enable_if<std::is_same<ReturnType, void>::value, ReturnType>::type callImpl ( Arguments ... args) { std::cout << "Calling with void\n"; return; } template <typename ReturnType, typename ...Arguments> typename std::enable_if<std::is_same<ReturnType, bool>::value, ReturnType>::type callImpl (Arguments ... args) { std::cout << "Calling with bool\n"; return true; } template <typename ReturnType, typename ...Arguments> typename std::enable_if<std::is_same<ReturnType, int>::value, ReturnType>::type callImpl (Arguments ... args) { std::cout << "Calling with int\n"; return 42; } }; int main(int argc, char *argv[]) { Caller c; auto rbool = c.call<bool> (1,20); std::cout << "Return: " << rbool << "\n"; auto rint = c.call<int> (1,20); std::cout << "Return: " << rint << "\n"; // the next line fails compilation. compile with --std=c++11 c.call<void>("abababa"); return 0; }
- Update -
Not a big problem: use std::bind(&Caller::callImpl<ReturnType>, this, args) .