Я не могу инициализировать элементы std::tuple
элементов из std::tuple
совместимых типов. Почему он не работает как с boost::tuple
?Почему std :: tuple не может быть поэтапно построен с использованием std :: 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
неtrue
для всехi
.
std::is_constructible<Foo<int>, int>::value
является true
. Из ошибки шаблона GCC я вижу, что перегрузка no. 3:
template <class... UTypes>
explicit tuple(UTypes&&... args);
выбран вместо этого. Зачем?
Хорошо, он не работает с '-std = libstdC++', но работает с '-std = libC++' на Clang. Должна быть проблема внедрения. – LogicStuff
Пожалуйста, укажите ошибку в bugzilla gcc. –
Этот вопрос по-прежнему будет давать ценную информацию для тех, кто столкнется с одной и той же проблемой. Он скажет им, что проблема связана со стандартной реализацией библиотеки, а не с кодом. Есть много общих целей обмана, которые являются объяснением конкретной ошибки реализации (например, MinGW и 'stoi') –