两种相同的方法,但编译器选择模板化的方法

问题描述 投票:0回答:1

我正在尝试用 C++ 实现一个列表容器,但编译器选择错误的重载时遇到问题。

重载如下:

list(size_type count, const T& value);
template<typename InputIt>
list(InputIt begin, InputIt end);

当我初始化源文件中的对象时,我无法阻止编译器选择第二个重载:

list<int> x(5, 45);

当给定的参数可迭代时,应该选择第二个重载,但我无法完成它。感谢您的帮助。

编辑:

类声明如下所示:

template<typename T, typename Allocator = std::allocator<T>> 
class list {
public:
    using value_type = T;
    using pointer = T*;
    using const_pointer = const T*;
    using reference = T&;
    using const_reference = const T&;
    using move_reference = T&&; // custom
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    list(size_type count, const T& value);
    template<typename InputIt>
    list(InputIt begin, InputIt end);

    // ...
};
c++ c++17
1个回答
0
投票

当给定的参数可迭代时,应该选择第二个重载,但我无法完成它。

您需要SFINAE(“替换失败不是错误”)C++17 中的两个构造函数。

// Constructor for count and value
template<typename U = T, typename = std::enable_if_t<std::is_constructible_v<T, const T&>>>
list(std::size_t count, const T& value)
/* : contr init list */
{
    std::cout << "list(std::size_t count, const T& value) \n";
}

// Constructor for iterator range
template<typename InputIt, typename U = T, typename = std::enable_if_t<std::is_constructible_v<T, typename std::iterator_traits<InputIt>::value_type>>>
list(InputIt begin, InputIt end)
/* : contr init list */
{
    std::cout << "list(InputIt begin, InputIt end)\n";
}

观看现场演示


但是,在 C++20 中,只需约束

std::input_or_output_iterator
的构造函数:

template<typename InputIt>
    requires (std::input_or_output_iterator<InputIt>)
list(InputIt begin, InputIt end) {}

观看现场演示

© www.soinside.com 2019 - 2024. All rights reserved.