代码之家  ›  专栏  ›  技术社区  ›  Robinson

访问模板中函数模板参数的结果类型?

  •  2
  • Robinson  · 技术社区  · 14 年前

    给定以下模板:

    template<class T>
    class Container
    {
    private:
    
        boost::function<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);
    }
    

    我猜这里有一个解决方案,但它可能涉及一些可怕的模版元编程解决方案。我知道格雷戈·坎托疯狂地思考着无限。。。模板元编程对我有同样的影响:p。

    谢谢你的任何想法。

    罗宾逊

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

    3 回复  |  直到 14 年前
        1
  •  3
  •   UncleBens    14 年前

    我不认为你真的需要专门处理void返回类型。一个void函数可以返回另一个void函数的“结果”。

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

    boost::function 有一个typedef result_type (见 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;
    

    编辑: 既然你知道 结果类型 是,并且您确实需要区分无效/非无效结果,您可以使用 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
  •  3
  •   James McNellis    14 年前

    是的,你可以用 boost::function_traits result_type 类型定义。

        3
  •  0
  •   sth Alien    14 年前

    取决于你想做什么,也许你让事情变得比必要的更复杂。如果 f 你打电话进来 void case本身就是一个空函数,你只要保持 return

    显式返回“void值”是可以的:

    void f() {
    }
    
    void g() {
       return f();
    }