该标准说std::tuple
具有以下成员函数
constexpr tuple();
explicit tuple(const Types&...);
可有人请解释什么是应该发生的std::tuple<>
该标准说std::tuple
具有以下成员函数
constexpr tuple();
explicit tuple(const Types&...);
可有人请解释什么是应该发生的std::tuple<>
我相信这是标准的一个小错误。 显然,当所述Types
参数包是空的,这两个构造函数调用是等效的,并且不能被重载(参照C ++ 11第13部分)。 (另外请注意,使用构造Types
是不是一个成员模板要么--IF它,那么这将是一个合法的过载)。
换句话说,这个代码不会编译:
template <typename... Types>
struct Test
{
constexpr Test() {}
explicit Test(Types const&...) { /* etc. */ }
};
int main()
{
Test<> a;
Test<int> b;
}
例如,克++ V4.8快照输出:
tt.cxx: In instantiation of ‘struct Test<>’:
tt.cxx:10:10: required from here
tt.cxx:5:12: error: ‘Test<Types>::Test(const Types& ...) [with Types = {}]’ cannot be overloaded
explicit Test(Types const&...) { /* etc. */ }
^
tt.cxx:4:13: error: with ‘constexpr Test<Types>::Test() [with Types = {}]’
constexpr Test() {}
^
这可以是固定的,通过使用偏特:
template <typename... Types>
struct Test
{
constexpr Test() {} // default construct all elements
explicit Test(Types const&...) { /* etc. */ }
// and all other member definitions
};
template <>
struct Test<>
{
constexpr Test() {}
// and any other member definitions that make sense with no types
};
int main()
{
Test<> a;
Test<int> b;
}
这将正确编译。
它出现的标准需要一个constexpr
默认的构造函数,是因为这样std::tuple<> var;
可以写成代替书写std::tuple<> var();
或std::tuple<> var{};
因为使用的explicit
与其他构造。 不幸的是,它的定义std::tuple
没有为大小为0的元组工作。 标准确实允许这样在第20.4.2.7(关系运算符)不过,“对于任何两个零长度的元组,[...]。” 哎呀! :-)
我想在标准中给出的定义应该是伪代码。 这与很多标准的定义的情况下; 它包含了口头方式发出通知,但只与像花样可满足几个要求enable_if
。 这似乎是一个例子,其中的C ++ - 试图实例化这样一个空的元组(或者它可能只是一个遗漏),当像伪代码符号实际上导致非法C ++。
既stdlibc ++和的libc ++具有零元素的元组的显式特。 例如,在stdlibc ++:
// Explicit specialization, zero-element tuple.
template<>
class tuple<>
{
public:
void swap(tuple&) noexcept { /* no-op */ }
};
与隐式定义明确的默认构造函数。
的libc ++没有显式声明的参数的默认构造函数。 据推测,该模板构造函数,然后选择作为非空元组的默认构造函数。
有趣的是,这两个库不同意空的元组有什么成员。 例如,以下与libc中++编译,但不是的libstdc ++:
#include <tuple>
#include <memory>
int main() {
std::tuple<> t(std::allocator_arg, std::allocator<int>());
}
乍一看,模糊只在无关紧要的地方就是所谓的点,然后你有正常的重载解析。