gpt4 book ai didi

c++ - forward_list : assign(_InputIterator __first, _InputIterator __last)/assign(size_type __n, const _Tp& __val)

转载 作者:行者123 更新时间:2023-11-30 03:52:16 25 4
gpt4 key购买 nike

我已经实现了 forward_list 的一个子集并想测试方法 assign(size_type __n, const _Tp& __val) 但是我得到了一个编译器错误,因为编译器想要改为调用方法 assign(_InputIterator __first, _InputIterator __last)

我写了下面的片段,只是为了说明问题:

测试.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

测试.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,无需转换),而非模板将必须进行提升(必须提升10intsize_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 : assign(_InputIterator __first, _InputIterator __last)/assign(size_type __n, const _Tp& __val),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30809075/

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