首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ 11比较参数包

C++ 11比较参数包
EN

Stack Overflow用户
提问于 2016-02-25 17:00:37
回答 1查看 1.2K关注 0票数 0

我正试图把我的头围绕参数包,并需要一点帮助。

看看下面这个精心设计的例子,有没有办法将Args与T进行比较,并且只允许bar()在它们匹配的情况下进行编译?例如,如果我创建了Task<void(int, char, float)>,我希望bar(float, char, float)不是编译,而是bar(int, char, float)编译得很好。这是否可行呢?

代码语言:javascript
复制
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);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-25 17:28:15

首先,语法应该是:

代码语言:javascript
复制
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的转换时存在实例化。

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

代码语言:javascript
复制
#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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35633638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档