gpt4 book ai didi

C++,实现函数时出现奇怪的编译器错误 `int next(std::string param)`

转载 作者:IT老高 更新时间:2023-10-28 21:39:23 28 4
gpt4 key购买 nike

我被下面的代码严重咬了一口,浪费了我好几个小时的宝贵时间。

#include<string>

int next(std::string param){
return 0;
}

void foo(){
next(std::string{ "abc" });
}

这会产生以下编译器错误(在 Visual Studio 2013 上):

1>------ Build started: Project: sandbox, Configuration: Debug Win32 ------
1> test.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2039: 'iterator_category' : is not a member of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
1> c:\users\ray\dropbox\programming\c++\sandbox\test.cpp(8) : see reference to class template instantiation 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>' being compiled
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2146: syntax error : missing ';' before identifier 'iterator_category'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2602: 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category' is not a member of a base class of 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371) : see declaration of 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2868: 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category' : illegal syntax for using-declaration; expected qualified-name
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我后来发现,如果我将函数名称从 next() 更改为其他名称,一切都很好。对我来说,这表明存在名称冲突,特别是名称next。我觉得这很奇怪,因为我没有使用 using namespace std 之类的东西。据我所知, next 不是内置的 C++ 关键字(是吗?)。我查找了下一个 here ,但它是std::next,正如我所说,我没有使用命名空间std。那么这场冲突是如何发生的呢?我如何防止将来发生类似的事情?还有哪些名称可能会导致这样的冲突?

最佳答案

这里发生了几件事,以微妙的方式相互作用。

首先,对 next 的无条件调用带有 std::string 类型的参数意味着以及您自己的next函数,标准函数模板std::nextArgument-dependent lookup 找到(ADL)。

在名称查找找到您的::next 后和标准库的std::next它执行重载决议,以查看哪个更适合您调用它的参数。

std::next 的定义看起来像:

template <class ForwardIterator>
ForwardIterator next(ForwardIterator x,
typename std::iterator_traits<ForwardIterator>::difference_type n = 1);

这意味着当编译器执行重载解析时,它会替换类型 std::string进入 std::iterator_traits<std::string> .

C++14 之前的 iterator_traits is not SFINAE-friendly这意味着用不是迭代器的类型来实例化它是无效的。 std::string不是迭代器,所以它是无效的。 SFINAE规则在这里不适用,因为错误不在 immediate context 中。 ,所以使用 iterator_traits<T>::difference_type对于任何非迭代器T将产生一个硬错误,而不是替换失败。

您的代码应该在 C++14 中正常工作,或者使用已经提供 SFINAE 友好的不同标准库实现 iterator_traits ,比如 GCC 的库。相信微软也会提供对SFINAE友好的iterator_traits用于 Visual Studio 的下一个主要版本。

为了使您的代码现在可以工作,您可以对 next 的调用进行限定。所以不执行 ADL:

::next(std::string{ "abc" });

这表示调用 next在全局命名空间中,而不是任何其他 next可能会通过非限定名称查找找到。

关于C++,实现函数时出现奇怪的编译器错误 `int next(std::string param)`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29594986/

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