一组具有共同点的非连贯类型(概念数组)

an array of non-coherent types, that have something in common (array of concepts)

我认为这种用例很常见,当您有多个具有共同元素(变量或 fcn)的模板化 classes 时,您希望在一个循环中为所有这些模板调用 fcn -喜欢的方式。

显然,我们可以定义一个基 class 并制作一个基 class 指针列表,并使用它们进行循环,但我试图避免指针(用于复制问题)和虚函数(出于优化原因)

template <typename T> 
struct A {T _value; void foo(){cout<<_value;}};

A<int> a_1{1}; A<float> a_2{2.0f}; ...

void foo_all(){ a_1.foo(); a_2.foo(); ... }

// for (auto i :{a_1,a_2, ...}) is not possible
// array<A<T>,10>; is not also possible, if T is variable

这个用例是否有某种设计模式/习语 是否计划在未来某个时候为概念提供一个可迭代的容器?

正在尝试 variadic template

template <typename T, typename... Types>
void callAll(T&& value, Types&&... values) {
    value.foo();
    if constexpr (sizeof...(values) > 0) {
        callAll(values...);
    }
}

然后

callAll(a_1, a_2);

Demo

如果您使用的是 C++20,您可以使用 concepts 来限制参数类型。

template<typename T>
concept IsA = requires(T x)
{
    { x.foo() };
};

template <typename T, typename... Types>
requires IsA<T>
void callAll(T&& value, Types&&... values)

我通过实现自己的元组(没有分配)找到了解决方案

template <typename T1, typename... Tn> struct tuple
{
    tuple(T1&& first, Tn&&... rest): m_first(first), m_rest(std::forward<Tn>(rest)...){};
    T1 m_first; tuple<Tn...> m_rest;
};

template <typename T> struct tuple<T>  /*specialization*/
{ 
    tuple(T&& first): m_first(first){};
    T m_first; 
};

template<class functor,typename... Tn>
void apply(functor&& fcn, tuple<Tn...>& t) 
{ 
    fcn(t.m_first); 
    if constexpr(sizeof...(Tn)>1) apply(std::forward<functor>(fcn), t.m_rest); 
};

并打电话

apply([](auto& x){x.foo();},tuple{A<int>{1},A<float>{2.0f}});

另一种解决方案是使用 std::variant 和访问者函数

using var = std::variant<A<int>,A<float>>;
std::array<var ,2> arr {A<int>{1},A<float>{2.0f}};
std::visit([](auto& x){x.foo();}, arr);