2

给定以下模板:

模板<class T>
类容器
{
私人的:

    升压::函数<T> f;
};

...及其实例化,可能如下:


    Container<bool(int, int)> myContainer;

,有没有办法访问函数描述的返回类型并有条件地编译它?例如,如果调用者指定他的函数返回 bool(如上例所示),我想包含一个返回值的函数。如果他指定该函数为 void,我不希望包含此函数。例如:


// 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。

感谢您的任何想法。

罗宾逊

编辑:显然这可以通过实现一个不同的类(可能从一个公共基础派生)来解决,一个称为 VoidContainer 另一个称为 ReturnsContainer (或类似的)。然而这对我来说似乎有点不满意......

4

3 回答 3

3

是的,您可以使用boost::function_traits具有result_typetypedef 的 .

于 2010-08-18T16:51:32.900 回答
3

I don't think you actually need to specialize for void return type. A void function is allowed to return the "result" of another void function for exactly this scenario.

void foo() { }
void bar() { return foo(); } //this is OK

int main()
{
    bar();
}

So your only problem would be how to determine the return type.

It appears that boost::function has a typedef for result_type (see 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;

Edit: Now that you know what the result_type is, and you do need to distinguish between void/non-void results, you can employ enable_if and disable_if. The only complication is that those only work with function templates, so a non-template foo calls a templated 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();
}
于 2010-08-18T17:02:53.093 回答
0

取决于你想要什么,也许你让事情变得比必要的更复杂。如果f您在void案例中调用的 void 函数本身,您可以只保留return.

Explicitly returning a "void value" is ok:

void f() {
}

void g() {
   return f();
}
于 2010-08-18T17:00:36.067 回答