C++ 我可以在C++;?
我不确定这是否可行,但我可以说:C++ 我可以在C++;?,c++,templates,c++17,template-meta-programming,C++,Templates,C++17,Template Meta Programming,我不确定这是否可行,但我可以说: 使用my_variant=std::variant 现在,在某一点上,我创建了一个Class4,并希望扩展my_variant2,以包括所有my_variant2以及Class4(一般来说,不只是使用另一个使用…),这样我就可以创建一个数组std::array 这是可以做到的吗? #包括 模板结构连接器; 模板 结构串联器{ 使用type=std::variant; }; int main(){ 使用类型t=std::variant; 静态断言( std::是相
使用my_variant=std::variant代码>
现在,在某一点上,我创建了一个Class4
,并希望扩展my_variant2
,以包括所有my_variant2
以及Class4
(一般来说,不只是使用另一个使用…
),这样我就可以创建一个数组std::array
这是可以做到的吗?
#包括
模板结构连接器;
模板
结构串联器{
使用type=std::variant;
};
int main(){
使用类型t=std::variant;
静态断言(
std::是相同的吗<
连接器::类型,
标准:变体>);
返回0;
}
其中var
是var1
和var2
的变体类型的浓缩,实现这一点有两个步骤。第一个是识别原始std::variant
中使用的类型列表,第二个是用原始参数加上要添加的参数构造一个新的std::variant
类型
部分模板专门化可用于编写一个trait,该trait将获得给定std::variant
中使用的模板类型列表:
#include <variant>
template<class T>
struct t_variant_cat;
template<class ... Old>
struct t_variant_cat<std::variant<Old...>> {
// Old is a parameter pack containing all of
// template arguments of the std::variant
};
其用途是:
#include <variant>
template<class T, class New>
struct t_variant_cat;
template<class ... Old, class New>
struct t_variant_cat<std::variant<Old...>, New> {
using type = std::variant<Old..., New>;
};
template<class Old, class New>
using t_variant_cat_t = typename t_variant_cat<Old, New>::type;
using old = std::variant<int, float>;
using extended = t_variant_cat_t<old, double>;
// Makes sure this actually works
static_assert(std::is_same_v<extended, std::variant<int, float, double>>,
"Something is wrong.");
#包括
模板
结构t_变量t_cat;
模板
结构t_变量(cat){
使用type=std::variant;
};
模板
使用t_variant_cat_t=typename t_variant_cat::type;
使用old=std::variant;
使用扩展=t\u变量\u cat\t;
//确保这确实有效
静态断言(std::is_same_v,
“有点不对劲。”);
简单明了。我很惊讶,最复杂的答案竟然有比这更多的选票。@CássioRenan-我知道!有趣。我猜,这使得,std::variant
变成了一个具有标识的非交换幺半群std::variant
@Sebastian-让我用谷歌搜索了幺半群是什么(最后),但我同意,原则上,就像任何其他变量模板一样,似乎是这样。这个问题被错误地标记为C++14
(尽管std::variant
仅在C++17
中存在)。假设您可以通过使用std::is_same\u v
而不是std::is_same::value
从示例中切掉7个字节,并通过不定义t_variant\u cat再切掉2个字节,则只需声明:-D@bobah谢谢你的反馈。我会做出改变的。
extend_type<my_variant, Class4>
std::variant<Class1, Class2, Class3, Class4>
namespace impl_details {
template<class Lhs, class Rhs>
struct type_cat;
template<template<class...>class Z, class...Lhs, class...Rhs>
struct type_cat<Z<Lhs...>, Z<Rhs...>> {
using type=Z<Lhs..., Rhs...>;
};
}
template<class Lhs, class Rhs>
using type_cat = typename impl_details::type_cat<Lhs, Rhs>::type;
auto variant_trinary( bool b ) {
return [b](auto&& lhs, auto&& rhs) {
using R=type_cat< std::decay_t<decltype(lhs)>, std::decay_t<decltype(rhs)> >;
auto as_R = [](auto&&x)->R{ return decltype(x)(x)); };
if (b)
return std::visit( as_R, lhs );
else
return std::visit( as_R, rhs );
};
}
auto var = variant_trinary(bool_expr)( var1, var2 );
#include <variant>
template<class T>
struct t_variant_cat;
template<class ... Old>
struct t_variant_cat<std::variant<Old...>> {
// Old is a parameter pack containing all of
// template arguments of the std::variant
};
#include <variant>
template<class T, class New>
struct t_variant_cat;
template<class ... Old, class New>
struct t_variant_cat<std::variant<Old...>, New> {
using type = std::variant<Old..., New>;
};
template<class Old, class New>
using t_variant_cat_t = typename t_variant_cat<Old, New>::type;
#include <variant>
template<class T, class New>
struct t_variant_cat;
template<class ... Old, class New>
struct t_variant_cat<std::variant<Old...>, New> {
using type = std::variant<Old..., New>;
};
template<class Old, class New>
using t_variant_cat_t = typename t_variant_cat<Old, New>::type;
using old = std::variant<int, float>;
using extended = t_variant_cat_t<old, double>;
// Makes sure this actually works
static_assert(std::is_same_v<extended, std::variant<int, float, double>>,
"Something is wrong.");