我已经实现了forward_list
的一个子集,并想测试assign(size_type __n, const _Tp& __val)
方法,但是由于编译器想要调用assign(_InputIterator __first, _InputIterator __last)
方法,因此出现编译器错误。
我编写了以下代码片段,以说明问题:
test.h
#ifndef TEST_H
#define TEST_H
#include <utility> // Just to get the std::size_t
template<typename _Tp>
class forward_list {
public:
typedef std::size_t size_type;
void assign(size_type n, const _Tp& val)
{
printf("%s\n", __PRETTY_FUNCTION__);
}
template<typename _InputIterator>
void assign(_InputIterator first, _InputIterator last)
{
printf("%s\n", __PRETTY_FUNCTION__);
}
};
#endif // TEST_H
test.cpp
#include <stdlib.h>
#include <stdio.h>
#include "test.h"
int main()
{
forward_list<int> l;
l.assign(10, 5);
return 0;
}
执行的输出为:
void forward_list<_Tp>::assign(_InputIterator, _InputIterator) [with _InputIterator = int; _Tp = int]
我想调用
assign(size_type __n, const _Tp& __val)
方法。编译器版本(以防万一):
g++ (Debian 4.7.2-5) 4.7.2
我已经使用了与
std::forward_list
中使用的签名相似的签名,并使用了以下代码片段(使用STL):std::forward_list<int> l;
l.assign(10, 5);
编译器知道必须调用
assign(size_type __n, const _Tp& __val)
并且不会感到困惑。我想念什么? 最佳答案
调用l.assign(10, 5);
时,有两个可行的重载:
void assign(size_type n, const int& val)
template <>
void assign(int first, int last)
当我们说非模板函数比模板函数更可取时,只有当二者具有不可区分的转换序列时,这才是正确的。但是在这种情况下,功能模板将完全匹配(您的两个参数均为
int
,无需进行转换),而非模板将必须进行升级(必须将10
从int
升级为size_t
)。因此,首选函数模板重载。至于如何修复它,您只需要使模板不再可行即可。这涉及为输入迭代器编写type_trait,使用
void_t
并不难:template <typename... >
using void_t = void;
template <typename T, typename = void>
struct is_input_iterator : std::false_type { };
template <typename T>
struct is_input_iterator<T, void_t<
decltype(std::declval<T>() == std::declval<T>()),
decltype(std::declval<T>() != std::declval<T>()),
decltype(*std::declval<T>()),
decltype(++std::declval<T>()),
decltype(std::declval<T>()++)
>> : std::true_type { };
然后要求
is_input_iterator
:template <typename _InputIterator,
typename = std::enable_if_t<is_input_iterator<_InputIterator>::value>>
void assign(_InputIterator first, _InputIterator last);
还有很多其他方式可以执行这种操作,我碰巧喜欢
void_t
。无论采用哪种方式,都必须确保模板根本不可行。关于c++ - forward_list:分配(_InputIterator __first,_InputIterator __last)/分配(size_type __n,const _Tp&__val),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30809075/