【发布时间】:2016-11-11 21:53:20
【问题描述】:
我无法从兼容类型的std::tuple 逐元素初始化std::tuple 元素。为什么它不能像 boost::tuple 那样工作?
#include <tuple>
#include <boost/tuple/tuple.hpp>
template <typename T>
struct Foo
{
// error: cannot convert 'std::tuple<int>' to 'int' in initialization
template <typename U>
Foo(U &&u) : val(std::forward<U>(u)) {}
T val;
};
int main()
{
boost::tuple<Foo<int>>{boost::tuple<int>{}}; // ok
auto a = boost::tuple<int>{};
boost::tuple<Foo<int>>{a}; // ok
std::tuple<Foo<int>>{std::tuple<int>{}}; // fails with rvalue
auto b = std::tuple<int>{};
std::tuple<Foo<int>>{b}; // fails with lvalue
}
Live on Coliru(GCC 或 Clang 和 libstdc++ 无法编译,但是 Clang 和 libc++ 编译没有错误)
std::tuple 没有进行元素构造,它实例化了Foo<int>::Foo<std::tuple<int>> 而不是Foo<int>::Foo<int>。我认为std::tuple::tuple overloads no. 4 and 5 正是为此目的:
template <class... UTypes>
tuple(const tuple<UTypes...>& other);
template <class... UTypes>
tuple(tuple<UTypes...>&& other);
注意:
不参与重载决议,除非
std::is_constructible<Ti, const Ui&>::value对于所有i都是true。
std::is_constructible<Foo<int>, int>::value 是 true。从 GCC 模板错误中,我可以看到重载号。 3:
template <class... UTypes>
explicit tuple(UTypes&&... args);
而是选择了 。为什么?
【问题讨论】:
-
好的,它不适用于
-std=libstdc++,但适用于 Clang 上的-std=libc++。必须是实施问题。 -
请在 gcc 的 bugzilla 中提交一个错误。
-
这个问题仍然会为遇到同样问题的人提供有价值的信息。它会告诉他们问题出在标准库实现上,而不是在他们的代码中。有许多常见的欺骗目标是对特定实现错误的解释(例如 MinGW 和
stoi)
标签: c++ templates c++11 stdtuple boost-tuples