gpt4 book ai didi

c++ - 同一类的多种明确构造函数

转载 作者:搜寻专家 更新时间:2023-10-31 00:08:48 25 4
gpt4 key购买 nike

我有以下类(class):

class Foo
{
public:
// Constructors here
private:
std::vector<X> m_data; // X can be any (unsigned) integer type
};

我想让下面的代码工作:

Foo f0;
Foo f1(1); // and/or f1({1})
Foo f2(1, 2); // and/or f2({1, 2})
Foo f3(1, 2, 3); // and/or f3({1, 2, 3})
Foo f4(1, 2, 3, 4); // ... and so on
std::vector<int> vec = {1, 2, 3, 4};
Foo f5(vec);
Foo f6(vec.begin(), vec.end());
std::list<std::size_t> list = {1, 2, 3, 4};
Foo f7(list);
Foo f8(list.begin(), list.end());
std::any_iterable_container container = {1, 2, 3, 4};
Foo f9(container);
Foo f10(container.begin(), container.end());
// PS: I guess I only want containers/iterators that store individual
// values and not pairs (e.g., I don't want care about std::map
// because it does not make sense anyway).

到目前为止,我已经尝试将 SFINAE、构造函数重载与所有可能的类型、可变参数模板等结合起来。每次我修复一个构造函数案例时,其他的都会崩溃。此外,我编写的代码变得非常复杂且难以阅读。然而,这个问题看起来很简单,我想我只是以错误的方式接近它。关于如何编写构造函数(最好是在 C++17 中)同时保持代码尽可能简单的任何建议,我们都非常欢迎。

谢谢。

最佳答案

实现 f1-f4 的最简单方法(它似乎采用可变数量的已知类型 T 的参数,但不是容器或迭代器)是这样的:

template<typename... Args>
Foo(T arg, Args... args) {...}

由于此构造函数至少接受 1 个参数,因此与默认构造函数 f0 没有歧义。由于第一个参数是 T 类型,因此以下构造函数没有歧义。

如果你想以不同于其他容器的方式对待 std::vectorstd::list,你可以创建一个部分专用的辅助模板来检查参数是否是给定模板的实例:

template<typename>
struct is_vector : std::false_type {};

template<typename T, typename Allocator>
struct is_vector<std::vector<T, Allocator>> : std::true_type {};

然后像这样使用它来实现 f5f7:

template<typename T, Constraint = typename std::enable_if<is_vector<typename std::remove_reference<T>::type>::value, void>::type>
Foo(T arg) {...}

通过测试 std::vectorstd::list 各自的迭代器类型,您可以实现 f6f8 以同样的方式。

您可以检查是否存在成员函数 begin()end() 来实现 f9(我想),如下所示:

template<typename T>
Foo(T arg, decltype(arg.begin())* = 0, decltype(arg.end())* = 0) {...}

但是,您必须使用您创建的辅助模板为 std::vectorstd::list 显式禁用此构造函数以避免歧义。

要检查参数是否是实现 f10 的某个迭代器,您可以使用 std::iterator_traits:

template<typename T, typename Constraint = typename std::iterator_traits<T>::iterator_category>
Foo(T begin, T end) {...}

同样,对于 std::vectorstd::list 的迭代器类型,您必须显式禁用此构造函数。

关于c++ - 同一类的多种明确构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46862039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com