使用使用声明模板化的参数实例化嵌套类模板

时间:2015-07-06 16:09:21

标签: c++ templates c++11

在阅读how to get a parameter types of a function pointerhow to get the a return value of a function pointer (with cv-qualifier overloads)上的答案后,我决定将它们合并到一个function_traits类模板中:

#include <tuple>

using uint = unsigned int;

template <typename T>
struct function_traits;

template <typename R, typename ... Args>
struct function_traits<R(Args...)>
{
    using return_t = R;
    static const uint args_count = sizeof...(Args);

    template <uint i>
    struct arg
    {
        using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
    };
};

template <typename R, typename ... Args>
struct function_traits<R(*)(Args...)>
{
    using return_t = R;
    static const uint args_count = sizeof...(Args);

    template <uint i>
    struct arg
    {
        using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
    };
};

template <typename R, typename C, typename ... Args>
struct function_traits<R(C::*)(Args...)>
{
    using return_t = R;
    using class_t = C;
    static const uint args_count = sizeof...(Args);

    template <uint i>
    struct arg
    {
        using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
    };
};

// cv-qualifier overloads ...

上面的代码工作正常,但我也想提供一些typedef来帮我打字。但是,当我尝试使用模板参数arg_t实例化嵌套类模板arg时,编译器在i上给出了错误。我不熟悉模板,所以这可能是我在这里缺少的基本功能。它是什么?

template <typename T>
using return_t = typename function_traits<T>::return_t;

template <typename T>
using class_t = typename function_traits<T>::class_t;

template <typename T, uint i>
using arg_t = typename function_traits<T>::arg<i>::type;
//                                            ^
//                                    ';' expected here

以下是Coliru的输出。

1 个答案:

答案 0 :(得分:2)

由于 <bean id="processEngineFactory" class="com.bp3.oss.custom.ProcessEngineFactoryWithELResolverReordered" init-method="init" destroy-method="destroy"> <property name="processEngineConfiguration" ref="configuration"/> <property name="bundle" ref="blueprintBundle"/> <property name="blueprintELResolver" ref="blueprintELResolver"/> <property name="blueprintContextELResolver" ref="blueprintContextELResolver"/> </bean> 是模板的成员,因此您需要在代码中指定它是模板。您需要指定此项,因为arg<i>可能是模板,或者不是模板,具体取决于arg的特化。如果模板是类型或模板,则需要指定模板的成员。您作为程序员需要告诉编译器function_traits是一个模板。你可以这样做:

arg<i>

看起来很奇怪,但这就是C ++的方式。