C ++ 11比较参数包

时间:2016-02-25 17:00:37

标签: c++11 variadic-templates

我试图绕过参数包并需要一些帮助。

看看下面的人为举例,有没有办法将Args与T进行比较,只允许bar()编译才能匹配?例如,如果我创建Task<void(int, char, float)>我希望bar(float, char, float)不要编译,而bar(int, char, float)编译就好了。这甚至可行吗?

template <typename... Types>
struct foo {};

template<typename T>
struct Task;

template<typename R, typename...Args>
struct Task<R(Args...)>
{
    template<typename... T>
    std::enable_if<is_same<T, Args>
    void bar(T... args)
    {
        //do something here 
    }          
};

int main()
{
    Task<int(int)> task;
    int a = 0;
    float b = 1.0;
    bool c = false;

    //compiles
    task.bar(a);

    //none of these should compile
    task.bar(b);
    task.bar(c);
    task.bar(a, b);
    task.bar(a, b, c);
}

1 个答案:

答案 0 :(得分:0)

首先,语法应该是:

template<typename R, typename...Args>
struct Task<R(Args...)>
{
    template<typename... T>
    std::enable_if<is_same<tuple<T...>, tuple<Args...> >::value > bar(T... args)
    {
        //do something here 
    }          
};

由于SFINAE,编译很好:例如,在尝试实例化bar(bool)时,第一个实例化失败了bool类型,但在执行参数转换为int时存在实例化。

要获得所需的效果,您需要在实例化模板后进行硬类型检查:

#include <type_traits>
#include <tuple>

template<typename T>
struct Task;

template<typename R, typename... Args>
struct Task<R(Args...)>
{
    template<typename... OtherArgs>
    void bar(OtherArgs... otherArgs)
    {
        static_assert(
            std::is_same<std::tuple<Args...>, std::tuple<OtherArgs...> >::value,
            "Use same args types !"
        );
        // Do something
    }
};

int main()
{
    Task<int(int)> task;
    // Compiles fine
    task.bar(1);
    // Fails to compile
    task.bar('u');
    task.bar(0ul);
    return 0;
}