Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我可以在C++;?_C++_Templates_C++17_Template Meta Programming - Fatal编程技术网

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