C++:是否可以编写一个函数,将不同类型的元素附加到变体数组中?
C++: Is it possible to write a function that appends a differently typed element to an array of variant?
我正在尝试编写一个函数,例如,它将采用:
std::array<std::variant<int, std::string_view>, 4>
和double d
,然后返回:
std::array<std::variant<int, std::string_view, double>, 5>
将d
附加到数组的末尾,但到目前为止,我在实现中遇到了一些非常奇怪的行为。
现在,我有一个Variant_Monoid
(带有二进制操作concatenate
(来处理扩展std::variant
类型,这似乎工作正常:
struct Variant_Monoid {
using zero = std::monostate;
template <typename T, typename... Args>
struct [[maybe_unused]] concatenate;
template <typename... Args0, typename... Args1>
struct concatenate<std::variant<Args0...>, std::variant<Args1...>> {
using type = std::variant<Args0..., Args1...>;
};
// Convenience method to concatenate types without having to wrap them into a variant first.
template<typename... Args0, typename... Args1>
struct concatenate<std::variant<Args0...>, Args1...> {
using type = std::variant<Args0..., Args1...>;
};
};
然后我有这个,其中的想法是遍历现有数组,尝试将类型从旧变体扩展到新变体,然后附加新元素:
template<size_t N, typename T, typename S>
constexpr std::array<typename Variant_Monoid::concatenate<T, S>::type, N + 1> append_element_with_type(const std::array<T, N> &a, const S &s) {
return append_element_with_type_aux(a, s, std::make_index_sequence<N>{});
}
委托给此函数:
template<size_t N, typename T, typename S, size_t... Indices>
constexpr std::array<typename Variant_Monoid::concatenate<T, S>::type, N + 1>
append_element_with_type_aux(const std::array<T, N> &a,
const S &s, std::index_sequence<Indices...>) noexcept {
return {{std::visit([](auto &&t) { return t; }, a[Indices])..., s}};
}
但是,此函数的行为无处不在。在某些情况下(通常是一系列调用中的第一个调用(,它似乎工作正常。例如:
constexpr std::array<std::variant<Variant_Monoid::zero>, 0> s0{};
constexpr std::array<std::variant<Variant_Monoid::zero, int>, 1> s1 = append_element_with_type(s0, 1);
但是,如果我接下来尝试此操作,编译器不仅抱怨表达式未constexpr
,而且无法使用一连串无法破译的 STL 消息进行编译:
auto s2 = append_element_with_type(s1, 3.14159);
同样,这似乎可以毫无问题地工作:
constexpr std::array<std::variant<std::string_view>, 3> to_extend = {{"Hello", "there", "world"}};
constexpr std::array<std::variant<std::string_view, int>, 4> extended = append_element_with_type(to_extend, 5);
然后,这又失败了,并出现类似的编译错误,并再次声称表达式未constexpr
:
constexpr std::array<std::variant<std::string_view, int, double>, 5> prepended = append_element_with_type(extended, 3.14);
任何建议/帮助将不胜感激。我对模板元编程仍然相当陌生,只是为了了解更多信息而四处玩耍。
对所有可能的参数,对访问者的调用必须产生相同的类型和值类别。明确指定 lambda 的返回类型为新变体,即typename Variant_Monoid::concatenate<T, S>::type
。
相关文章:
- 在C++中,如何通过几种类型从元组中选择多个元素
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 如何为 c++ 的不同变量类型的结构元素创建动态数组?
- 创建一个函数来转换数组元素的类型并返回数组的地址
- std::矢量插入,不知道元素的类型
- 维护对元素参考类型
- 将空元素添加到声明的容器中,而不声明元素的类型
- 如何在函数模板中隐式推导数组中元素的类型信息
- 我怎么知道基类对象的指针数组中元素的类型,它将为派生类分配内存
- 避免强制转换容器的元素指针类型
- 从数组的类型中找到元素的类型
- 如何获取结构的元素作为类型提升::shared_ptr
- 对象向量的某些元素的类型转换
- 如何创建具有指定数量的元素(相同类型)的 boost::tuple
- 推导出 C++11 中元组元素的类型
- 数组中一元'*'(具有"int")最低元素的类型参数无效
- 在c++中,当元组的元素索引在运行时已知时,是否有可能获得该元素的类型?
- c++ map中元素的类型
- 获取数组元素的类型
- 如何确定数组元素的类型