一组具有共同点的非连贯类型(概念数组)
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);
如果您使用的是 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);
我认为这种用例很常见,当您有多个具有共同元素(变量或 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);
如果您使用的是 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);