gpt4 book ai didi

c++ - 如何为类似元组的可变参数类创建完美的转发构造函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:26:10 25 4
gpt4 key购买 nike

我正在尝试创建类似于元组的东西,但我在编写构造函数时遇到了问题。

代码如下:

#include <tuple>

template <typename... Ts>
struct B {
template <typename... ArgTypes>
explicit B(ArgTypes&&... args)
{
static_assert(sizeof...(Ts) == sizeof...(ArgTypes),
"Number of arguments does not match.");
}
};

struct MyType {
MyType() = delete;
MyType(int x, const char* y) {}
};

int main()
{
B <int, char> a{2, 'c'}; // works
B <int, bool, MyType, char> b{2, false, {4, "blub"}, 'c'}; // fails
std::tuple<int, bool, MyType, char> t{2, false, {4, "blub"}, 'c'}; // works
}

现在,如果将简单类型作为初始值设定项传递,这就可以正常工作,但如果我尝试为非平凡对象传递大括号括起来的初始值设定项列表中的参数,它就不行了。

GCC-4.7 发出以下内容:

vararg_constr.cpp:21:67: error: no matching function for call to 'B<int, bool, MyType, char>::B(<brace-enclosed initializer list>)'
vararg_constr.cpp:21:67: note: candidates are:
vararg_constr.cpp:6:14: note: B<Ts>::B(ArgTypes&& ...) [with ArgTypes = {}; Ts = {int, bool, MyType, char}]
vararg_constr.cpp:6:14: note: candidate expects 0 arguments, 4 provided

Clang-3.1 以下内容:

vararg_constr.cpp:21:40: error: no matching constructor for initialization of
'B<int, bool, MyType, char>'
B <int, bool, MyType, char> b{2, false,{4, "blub"}, 'c'}; // fails
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
vararg_constr.cpp:6:14: note: candidate constructor not viable: requires 2
arguments, but 4 were provided
explicit B(ArgTypes&&... args)

好的,现在让我非常非常好奇的是它对元组有效!根据标准 (20.4.2.1),它有一个构造函数,看起来很像我的。

template <class... Types>
class tuple {
public:
// ...

template <class... UTypes>
explicit tuple(UTypes&&...);

// ...
};

当以同样的方式构造元组对象时,它起作用了!

现在我想知道:

A) 到底是什么?为什么 std::tuple 如此特别,为什么编译器不能推断出正确的参数数量?

B) 我怎样才能使它工作?

最佳答案

A) 为什么编译器应该知道 {4, "blub"}是 MyType 类型而不是 tuple<int, const char*>

B) 在构造函数中将 ArgTypes 更改为 Ts:

explicit B(Ts&&... args)

元组也有以下构造函数:

  explicit constexpr tuple(const _Elements&... __elements);

编辑:要点是,调用带有 const& 的构造函数,而不是带有 R 值的构造函数。请考虑以下事项:

template <typename... Ts>
struct B {
explicit B(const Ts&... elements) { std::cout << "A\n"; }
template<typename... As,
typename = typename std::enable_if<sizeof...(As) == sizeof...(Ts)>::type>
explicit B(As&&... elements) { std::cout << "B\n" ;}
};

int main()
{
MyType m {1, "blub"};
B<int, char> a{2, 'c'}; // prints B
B<bool, MyType, char> b{false, {4, "blub"}, 'c'}; // prints A
B<bool, MyType, MyType>c{false, {4, "blub"}, std::move(m)}; // prints A
}

关于c++ - 如何为类似元组的可变参数类创建完美的转发构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9550106/

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