gpt4 book ai didi

c++ - 没有歧义的标识符

转载 作者:可可西里 更新时间:2023-11-01 17:49:14 25 4
gpt4 key购买 nike

Visual C++ 2017 干净地编译以下内容,调用用户定义的 log:

// Source encoding: UTF-8 with BOM ∩
#include <algorithm> // std::for_each
#include <iostream>
#include <math.h> // ::(sin, cos, atan, ..., log)
#include <string> // std::string

void log( std::string const& message )
{
std::clog << "-- log entry: " << message << std::endl;
}

auto main()
-> int
{
auto const messages = { "Blah blah...", "Duh!", "Oki doki" };
std::for_each( messages.begin(), messages.end(), log ); // C++03 style.
}

我认为这是一个编译器错误,因为我设计的代码是为了说明标识符如何因与标准库的名称冲突而变得不明确。

这是编译器错误吗?


补充信息:MinGW g++ 7.2 发出多条错误消息。它们并没有提供足够的信息,有 15 行提示 std::for_each,但显然它们是由于名称冲突造成的。更改 log 的名称,代码可以很好地编译。


更新:进一步检查表明这显然是一个编译器错误,因为 Visual C++ 编译了以下内容(定义符号 D 时除外):

#include <cmath>        // std::(sin, cos, atan, ..., log)
#include <string> // std::string

namespace my{ void log( std::string const& ) {} }
using std::log;
using my::log;

auto main()
-> int
#ifdef D
{ return !!log; }
#else
{ auto f = log; return f==my::log; }
#endif

Reported to Microsoft (新的 MS 错误报告方案有很多错误:它认为将代码自动换行是个好主意,然后拒绝让我上传源代码文件,除非我给它一个“.txt”文件扩展名)。

最佳答案

这是一个编译器错误,因为编译器不应该为 for_each 调用执行模板参数推导。

唯一可以匹配的 for_each 声明定义为 [alg.foreach] :

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);

应用于函数参数f 的模板参数推导需要函数调用参数log 的类型才能继续。但是log是重载的,重载的函数集没有类型。

例如,出于同样的原因,不应编译这段更简单的代码:

#include <algorithm>    // std::for_each
#include <string> // std::string

void log( std::string const& message );
void log();

auto main()
-> int
{
auto const messages = { "Blah blah...", "Duh!", "Oki doki" };
std::for_each( messages.begin(), messages.end(), log ); //template argument deduction for template parameter Function failed.
}

它在这个版本的 MSVC 中工作,因为模板(以前是/)被实现为一种宏,所以 log 被作为名称传递,并且重载解析在logfor_each 的主体中被调用。


关于编辑:

表达式 !!log 等同于调用 bool operator(bool) 没有模板参数推导,编译器只是不知道 的哪个重载code>log 它可以用来转换为 bool

auto x=y 形式的声明中,x 的实际类型是使用模板参数推导推导出来的 [dcl.type.auto.deduct]/4 :

If the placeholder is the auto type-specifier, the deduced type T' replacing T is determined using the rules for template argument deduction. [...]

所以 MSVC 的行为是错误的,但是是一致的。

关于c++ - 没有歧义的标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49397553/

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