给定一个带模板参数的类typename T
和class Tuple
我想提供一个特殊的构造函数,如果Tuple
具有std::vector
类似成员函数reserve
和push_back
。如果Tuple
有没有这样的成员函数,那么我想提供一个特殊的构造,如果Tuple
是从类型转换为T
可变参数构造的,即我怎样才能有条件地切换两个具有相同签名的构造函数?
template<typename T, class Tuple>
class vector
{
template<typename... Elements,
typename = decltype(std::declval<Tuple>().push_back(T())),
typename = decltype(std::declval<Tuple>().reserve(size_type()))>
vector(Elements&&... elements)
{ /* ... */ }
template<typename... Elements, typename = typename = decltype(Tuple{ static_cast<T>(std::declval<Elements>())... })>
vector(Elements&&... elements)
{ /* ... */ }
};
问题1:显然,在代码上面的编译器不知道我想尽可能采用第一个构造函数。无论如何,我怎样才能达到理想的行为?
问题2:假设第一个构造函数不存在,为什么下面的代码会导致编译器错误“不能从初始化列表转换为
vector<double, Tuple<double>>
”:
template<typename T>
class Tuple
{
public:
Tuple() { }
Tuple(std::initializer_list<T>) { }
};
int main()
{
vector<double, Tuple<double>> x = { 1, 2, 3 };
return 0;
}
当两个条件('A'和'B')都不满足时发生了什么。然后,'ctor_tag'将是'no_tag'。我是否需要为该标签提供第三个构造函数? – 0xbadf00d
@ 0xbadf00d它取决于不满意是否是逻辑错误。如果不符合前提条件之一(实现类型的参数),则不执行no_tag情况会为您提供编译器错误。这可能非常有用。 –
@RichardHodges如果'Tuple'适合,我们的想法是有条件地启用这些构造函数。如果'Tuple'不适合,那么这些构造函数应该被禁用。不应该生成编译器错误,因为我不想强制'Tuple'满足两个条件之一。 – 0xbadf00d