强制执行某些类型的可变参数模板 [英] Enforce variadic template of certain type

查看:79
本文介绍了强制执行某些类型的可变参数模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将可变参数模板的类型强制为与早期设置的模板类型相同。在下面的示例中,我希望T和U是同一类型。

I would like to enforce the type of variadic template to be identical to an earlier set template type. In the below example, I'd like T and U to be the same type.

ideone.com上的代码

#include <iostream>
#include <string>

template<class T>
struct Foo {

    Foo(T val) {
        std::cout << "Called single argument ctor" << std::endl;
        // [...]    
    }    

    // How to enforce U to be the same type as T?
    template<class... U>
    Foo(T first, U... vals) {
        std::cout << "Called multiple argument ctor" << std::endl;
        // [...]   
    }

};

int main() {

    // Should work as expected.
    Foo<int> single(1);

    // Should work as expected.
    Foo<int> multiple(1, 2, 3, 4, 5);

    // Should't work (but works right now). The strings are not integers.
    Foo<int> mixedtype(1, "a", "b", "c");

    // Also shouldn't work. (doesn't work right now, so that is good)
    Foo<int> alsomixedtype(1, 1, "b", "c");
}


推荐答案

我们可以使用SFINAE来确保所有 U 类型都与 T 相同。需要注意的重要一点是 U 不仅是您暗示的一种类型,而且还列出了可能不同的类型。

We can use SFINAE to ensure that all U types are the same as T. An important thing to note is that U is not just one type as you imply, but a list of possibly disparate types.

template<class... U, std::enable_if_t<all_same<T, U...>::value>* = nullptr>
Foo(T first, U... vals) {
    std::cout << "Called multiple argument ctor" << std::endl;
    // [...]   
}

std :: enable_if_t 来自C ++ 14。如果那不是您的选择,请使用 std :: enable_if

std::enable_if_t is from C++14. If that's not an option for you, just use std::enable_if.

typename std::enable_if<all_same<T, U...>::value>::type* = nullptr>

all_same 可以实现为不同的方式。这是我喜欢使用布尔包的一种方法:

all_same can be implemented in a bunch of different ways. Here's a method I like using boolean packs:

namespace detail
{
    template<bool...> struct bool_pack;
    template<bool... bs>
    //if any are false, they'll be shifted in the second version, so types won't match
    using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
}
template <typename... Ts>
using all_true = detail::all_true<Ts::value...>;

template <typename T, typename... Ts>
using all_same = all_true<std::is_same<T,Ts>...>;

这篇关于强制执行某些类型的可变参数模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆