给出以下模板:
template<class T> class Container { private: boost::function<T> f; };
......及其实例化,可能如下:
Container<bool(int, int)> myContainer;
,有没有办法访问函数描述的返回类型并有条件地编译它?例如,如果调用者指定他的函数返回bool(如上例所示),我想包含一个返回值的函数。如果他指定函数无效,我不希望包含此函数。例如:
// Include if the return type of T is void
template<class T1, class T2>
void DoSomething(T1 t1, T2 t2)
{
f(t1, t2);
}
// Include if the return type of T is not void
template<class T1, class T2>
***whatever the return type is*** DoSomething(T1 t1, T2 t2)
{
return f(t1, t2);
}
我猜这里有一个解决方案,但它可能涉及一些可怕的混淆模板元编程解决方案。我知道Gregor Cantor疯狂地思考无限......模板元编程类型对我有同样的影响:p。
感谢您的任何想法。
RobinsonT
编辑:显然,这可以通过实现一个不同的类(可能是从一个公共基础派生)来解决,一个叫做VoidContainer,另一个叫做ReturContainer(或类似的)。然而这对我来说似乎有点不尽如人意了......
答案 0 :(得分:3)
是的,您可以使用boost::function_traits
,其result_type
类型为<{1}}。
答案 1 :(得分:3)
我认为你实际上不需要专门针对void返回类型。允许void函数返回另一个void函数的“结果”,恰好是这种情况。
void foo() { }
void bar() { return foo(); } //this is OK
int main()
{
bar();
}
所以你唯一的问题是如何确定返回类型。
boost::function
似乎有result_type
的typedef(参见http://beta.boost.org/doc/libs/1_37_0/doc/html/boost/functionN.html)
#include <boost/function.hpp>
template<class T>
class Container
{
public:
typedef typename boost::function<T>::result_type result_type;
private:
boost::function<T> f;
};
Container<bool(int, int)>::result_type r = true;
编辑:
既然您知道result_type
是什么,并且您确实需要区分无效/无效结果,那么您可以使用enable_if
和disable_if
。唯一的复杂因素是那些只能使用功能模板,因此非模板foo
会调用模板do_foo
。
#include <boost/function.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <cstdio>
template<class T>
class Container
{
public:
typedef typename boost::function<T>::result_type result_type;
result_type foo()
{
return do_foo<result_type>();
//note that this still works because you can return the void result! :)
}
private:
//use this if the result_type is void
template <class U>
typename boost::enable_if<boost::is_same<U, void>, U >::type do_foo()
{
std::puts("for void");
}
//else
template <class U>
typename boost::disable_if<boost::is_same<U, void>, U>::type do_foo()
{
std::puts("other");
return U();
}
private:
boost::function<T> f;
};
int main()
{
Container<void()> a;
a.foo();
Container<int()> b;
b.foo();
}
答案 2 :(得分:0)
根据你的想法,你可能会让事情变得更加复杂。如果您在f
案例中调用的void
本身就是无效函数,则可以保留return
。
显式返回“空值”即可:
void f() {
}
void g() {
return f();
}