Reputation: 1089
I'm trying to figure out how I can switch between boost functions and c++11 functions depending on what the platform I'm compiling it on has available. I know that c++ doesn't have template aliasing (pre-c++11) so I wrote the following, but I can't understand the error message or why it's not working:
#define FUNCTION_Boost
#if defined(FUNCTION_Boost)
#include <boost/function.hpp>
#elif defined(FUNCTION_STL)
#include <functional>
#endif
template<typename Res, typename... ArgTypes>
struct function {
#if defined(FUNCTION_Boost)
typedef boost::function<Res(ArgTypes...)> type;
#elif defined(FUNCTION_STL)
typedef std::function<Res(ArgTypes...)> type;
#endif
};
// In instantiation of ‘function<void()>’:
// error: function returning a function
void foo(function<void ()>::type f) {
f();
}
// this works fine
void bar(boost::function<void ()> f) {
f();
}
Upvotes: 1
Views: 666
Reputation: 7119
no need to define one more function
... everything could be done using using
;)
#define USE_BOOST_FUNCTION
#ifdef USE_BOOST_FUNCTION
# include <boost/function.hpp>
# define FUNCTION_NS boost
# else
# include <functional>
# define FUNCTION_NS std
# endif
#include <iostream>
namespace test {
using FUNCTION_NS::function;
}
int main()
{
test::function<void()> f = [](){ std::cout << __PRETTY_FUNCTION__ << std::endl; };
f();
return 0;
}
Upvotes: 1
Reputation: 12700
I have the impression that this code does not do what you think it does:
typename function<void ()>::type
binds "void ()" as Res just creating a function that returns a function.
what about:
...
void foo(typename function<void >::type f) {
f();
}
...
?
You can get something similar to the aliasing you are trying to get with boost::type_traits and boost::type_traits::function_traits specially. That said, I suspect that if you want a simple and portable solution, then the easiest to do is to use boost and wait for better times with C++ compilers and STL support for C++11.
Upvotes: 1