我正在尝试用 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);
// ...
};
当给定的参数是可迭代的但我无法完成它时,应该选择第二个重载?
您需要 SFINAE(“替换失败不是错误”) 构造函数之一(C++20 之前的版本),以便选择正确的构造函数。
// Constructor for iterator range
template<typename InputIt
, std::enable_if_t<
std::is_constructible_v<
T, typename std::iterator_traits<InputIt>::value_type>>* = nullptr
>
list(InputIt begin, InputIt end)
/* : contr init list */
{}
std::input_or_output_iterator
: 的构造函数
template<typename InputIt>
requires (std::input_or_output_iterator<InputIt>)
list(InputIt begin, InputIt end)
/* : contr init list */
{}
问题在于,模板化 ctor 是“更好的匹配”,因为它对于传递的参数 5
和 45
都是“完全匹配”
,而非模板化 ctor 需要从
int
到
size_type
的转换第一个参数
5
。
有多种方法可以解决此问题,如其他答案所示。特别是,使用 c++20,您可以在模板化 ctor 上使用
std::input_or_output_iterator
来约束它。