Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.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++ 呼叫类型';s标记的构造函数(如果可用),否则为默认值_C++_C++11_Constructor_Void_Template Meta Programming_C++17_C++2a - Fatal编程技术网

C++ 呼叫类型';s标记的构造函数(如果可用),否则为默认值

C++ 呼叫类型';s标记的构造函数(如果可用),否则为默认值,c++,c++11,constructor,void,template-meta-programming,c++17,c++2a,C++,C++11,Constructor,Void,Template Meta Programming,C++17,C++2a,我正试图构建一些代码来声明一个局部变量(比如类型test,如下所示)。如果存在特殊的标记参数,则该局部变量的构造应使用该构造函数,否则应使用默认构造函数 我们可以得出如下结论,我们专门构造void参数或标记参数,但编译器不喜欢这样: #include <iostream> using std::cout; struct Tag { }; template <bool z> struct helper { using type = void; }; template

我正试图构建一些代码来声明一个局部变量(比如类型
test
,如下所示)。如果存在特殊的
标记
参数,则该局部变量的构造应使用该构造函数,否则应使用默认构造函数

我们可以得出如下结论,我们专门构造
void
参数或
标记
参数,但编译器不喜欢这样:

#include <iostream>
using std::cout;

struct Tag { };

template <bool z>
struct helper {
  using type = void;
};
template <>
struct helper<true> {
  using type = Tag;
};

template <bool z>
static typename helper<z>::type get_arg() {
  return typename helper<z>::type();
}

struct test {
  test(void) { cout << "test(void)\n"; }
  test(Tag x) { cout << "test(Tag)\n"; }

  test(const test&) = delete;
  test(test&&) = delete;
};

template <typename T>
void try_construct() {
  // we would be selecting from one of these by template metaprogramming
  T a{typename helper<false>::type()};
  T b{typename helper<true>::type()};

  T c{get_arg<false>()};
  T d{get_arg<true>()};

  // Then do stuff with the suitably-constructed instance of T
  // . . .
}

int main(void) {
  try_construct<test>();

  return 0;
}
#包括
使用std::cout;
结构标记{};
模板
结构辅助程序{
使用类型=无效;
};
模板
结构辅助程序{
使用类型=标签;
};
模板
静态typename助手::类型get_arg(){
返回typename助手::type();
}
结构测试{
测试(无效){cout
命名空间详细信息{
模板
T可能是标记构造(std::true\u类型){
返回T(标记{});
}
模板
T可能是标记构造(std::false类型){
返回T();
}
}
模板
T可能是标记构造(){
返回细节::maybe_tag_构造(std::是可构造的{});
}
现在
auto t=maybe_tag_construct();
constructs
test
from
tag
iff它起作用

它也会在之前进行省略移动构造,而在没有移动构造的情况下会进行省略移动构造

为了传递
void
的实例,您需要“常规void”方案,该方案已在我上次检查的轨道上。

命名空间详细信息{
模板
T可能是标记构造(std::true\u类型){
返回T(标记{});
}
模板
T可能是标记构造(std::false类型){
返回T();
}
}
模板
T可能是标记构造(){
返回细节::maybe_tag_构造(std::是可构造的{});
}
现在
auto t=maybe_tag_construct();
constructs
test
from
tag
iff它起作用

它也会在之前进行省略移动构造,而在没有移动构造的情况下会进行省略移动构造


为了传递
void
的实例,您需要“常规void”方案,这是我最后一次检查的结果。

我认为以下几点是可行的:

#include <type_traits>

template <typename T, bool B = std::is_constructible<Tag, T>> struct H;
template <typename T>
struct H<T, false> {
  T t;
  H() : t() {}
};
template <typename T>
struct H<T, true> {
  T t;
  H() : t(Tag) {}
};

try_construct() {
  H<T> h;
  h.t;
}
#包括
模板结构H;
模板
结构H{
T;
H():t(){}
};
模板
结构H{
T;
H():t(Tag){}
};
try_construct(){
H;
h、 t;
}

我认为以下几点是可行的:

#include <type_traits>

template <typename T, bool B = std::is_constructible<Tag, T>> struct H;
template <typename T>
struct H<T, false> {
  T t;
  H() : t() {}
};
template <typename T>
struct H<T, true> {
  T t;
  H() : t(Tag) {}
};

try_construct() {
  H<T> h;
  h.t;
}
#包括
模板结构H;
模板
结构H{
T;
H():t(){}
};
模板
结构H{
T;
H():t(Tag){}
};
try_construct(){
H;
h、 t;
}

这与我们所尝试的非常接近,但在C++17之前的版本中,正如您所注意到的,它仍然要求移动构造函数(或回退复制构造函数,移动构造函数不是
=delete;
)在类型上定义。我暂缓接受。这与我们尝试过的非常接近,但在C++17之前的版本中,正如您所注意到的,它仍然要求移动构造函数(或回退复制构造函数,移动构造函数不是
=delete;
)在类型上定义。我暂且不接受这个问题。我现在意识到,在问了这个问题并得到了很好的答案之后,在使用上下文中,我们实际上需要一个移动或复制构造函数。我现在意识到,在问了这个问题并得到了很好的答案之后,在使用上下文中,我们将我仍然需要一个移动或复制构造函数。
#include <type_traits>

template <typename T, bool B = std::is_constructible<Tag, T>> struct H;
template <typename T>
struct H<T, false> {
  T t;
  H() : t() {}
};
template <typename T>
struct H<T, true> {
  T t;
  H() : t(Tag) {}
};

try_construct() {
  H<T> h;
  h.t;
}