c++ - 强制执行某种类型的可变参数模板

标签 c++ templates c++11 variadic-templates

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

code on 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 不仅仅是您所暗示的一种类型,而是一个可能不同类型的列表。

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

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

all_same 可以通过多种不同的方式实现。这是我喜欢使用 bool 包的一种方法:

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>...>;

关于c++ - 强制执行某种类型的可变参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30346652/

相关文章:

c++ - Google 测试自动注册是否避免静态初始化顺序失败?

c++ - 无法从C++中的抽象类绑定(bind)函数

不使用静态存储的基于 C++ 类型的缓存

c++ - qt图表等轴(轴应该形成正方形而不是矩形)

c++ - 这个模板中的类型是什么?

c++ - 检查成员函数时 SFINAE 测试失败

c++ - 模板函数中的参数推导失败

c++ - 管理 cmake 依赖 git 模块

c++ - Clang 为使用的类型别名发出 "unused type alias"警告

c++ - C++98 中的异构容器查找