gpt4 book ai didi

c++ - 如果可用,调用类型的标记构造函数,否则默认

转载 作者:行者123 更新时间:2023-11-27 22:42:58 25 4
gpt4 key购买 nike

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

我们能够得出的结果如下,我们专门构造一个 void 参数或一个 Tag 参数,但编译器不会像那样:

#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;
}

编译器输出:

$ g++ -std=c++11 -c foo.cpp 
foo.cpp: In instantiation of 'void try_construct() [with T = test]':
foo.cpp:38:23: required from here
foo.cpp:30:37: error: no matching function for call to 'test::test(<brace-enclosed initializer list>)'
T a{typename helper<false>::type()};
^
foo.cpp:30:37: note: candidates are:
foo.cpp:22:3: note: test::test(Tag)
test(Tag x) { cout << "test(Tag)\n"; }
^
foo.cpp:22:3: note: no known conversion for argument 1 from 'void' to 'Tag'
foo.cpp:21:3: note: test::test()
test(void) { cout << "test(void)\n"; }
^
foo.cpp:21:3: note: candidate expects 0 arguments, 1 provided
foo.cpp:33:23: error: no matching function for call to 'test::test(<brace-enclosed initializer list>)'
T c{get_arg<false>()};
^
foo.cpp:33:23: note: candidates are:
foo.cpp:22:3: note: test::test(Tag)
test(Tag x) { cout << "test(Tag)\n"; }
^
foo.cpp:22:3: note: no known conversion for argument 1 from 'helper<false>::type {aka void}' to 'Tag'
foo.cpp:21:3: note: test::test()
test(void) { cout << "test(void)\n"; }
^
foo.cpp:21:3: note: candidate expects 0 arguments, 1 provided

我们知道如何测试构造函数的存在,所以我离开了我们的示例。如果这最终与采用不同方法的解决方案相关,请随意采用该方法。

我们的最终目标是要求默认构造函数或 Tag 构造函数之一,而不是复制或移动构造函数。

最佳答案

namespace details {
template<class T>
T maybe_tag_construct(std::true_type) {
return T(Tag{});
}
template<class T>
T maybe_tag_construct(std::false_type) {
return T();
}
}
template<class T>
T maybe_tag_construct() {
return details::maybe_tag_construct<T>( std::is_constructible<T, Tag>{} );
}

现在auto t =maybe_tag_construct<test>();构造 test来自 Tag如果它有效。

它还在 之前省略了移动构造,并在 没有移动构造发生。

为了传递 void 的实例周围,​​您需要“常规无效”提案,该提案已按计划进行 上次我检查过。

关于c++ - 如果可用,调用类型的标记构造函数,否则默认,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46613584/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com