Я пытаюсь создать что-то похожее на кортеж, но я столкнулся с проблемой написания моего конструктора.
Вот код:
#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 выдает следующее:
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&&...);
// ...
};
При построении объекта кортежа таким же образом, он работает!
ТеперьЯ хотел бы знать:
А) Какого черта?Почему std :: tuple такой особенный, и почему компиляторы не определяют правильное количество аргументов?
B) Как я могу заставить эту работу работать?