gpt4 book ai didi

c++ - 不同 C++ 编译器之间自动类型推导不匹配

转载 作者:行者123 更新时间:2023-12-01 22:29:42 28 4
gpt4 key购买 nike

因此,我尝试以某种现代 C++ 风格实现点积 ( https://en.wikipedia.org/wiki/Dot_product ),并得出以下代码:

#include <iostream>

template<class... Args>
auto dot(Args... args)
{
auto a = [args...](Args...)
{
return [=](auto... brgs)
{
static_assert(sizeof...(args) == sizeof...(brgs));

auto v1 = {args...}, i1 = v1.begin();
auto v2 = {brgs...}, i2 = v2.begin();
typename std::common_type<Args...>::type s = 0;

while( i1 != v1.end() && i2!= v2.end())
{
s += *i1++ * *i2++;
}
return s;
};
};
return a(std::forward<Args>(args)...);
}

int main()
{
auto a = dot(1,3,-5)(4,-2,-1);
std::cout << a << std::endl;
}

在线:https://gcc.godbolt.org/z/kDSney还有:cppinsights

上面的代码可以很好地编译并执行 g++ ,但是clang (以及iccmsvc)窒息:

clang++ ./funcpp.cpp --std=c++17                                                                                                                                                                                                                                                        
./funcpp.cpp:12:4: error: 'auto' deduced as 'std::initializer_list<int>' in declaration of
'v1' and deduced as 'const int *' in declaration of 'i1'
auto v1 = {args...}, i1 = v1.begin();
^ ~~~~~~~~~ ~~~~~~~~~~
./funcpp.cpp:28:11: note: in instantiation of function template specialization
'dot<int, int, int>' requested here
auto a = dot(1,3,-5)(4,-2,-1);
^
1 error generated.

现在,如果我分解 v1 的定义, v2 , i1 , i2像:

auto v1 = {args...} ;
auto i1 = v1.begin();
auto v2 = {brgs...};
auto i2 = v2.begin();

clangmsvc没问题,icc仍然窒息:

<source>(10): error: static assertion failed

static_assert(sizeof...(args) == sizeof...(brgs));

^

detected during instantiation of "auto dot(Args...) [with Args=<int, int, int>]" at line 30

compilation aborted for <source> (code 2)

Execution build compiler returned: 2

但是,如果我删除有问题的 static_assert然后icc编译代码也没有问题。

除了(典型的)问题:哪个是正确的以及为什么:)具体问题是:

根据[dcl.spec.auto] :

if the type that replaces the placeholder type is not the same in each deduction, the program is ill-formed

clang正确识别出相关行中定义了两种不同的类型:'auto' deduced as 'std::initializer_list<int>' in declaration of 'v1' and deduced as 'const int *' in declaration of 'i1'所以我想听听您的意见是否:

感谢您阅读这个很长的问题。(作为奖励,如果有人能回答为什么 iccstatic_assert 上失败,那就太好了。)

最佳答案

从我的评论中扩展:

g++ 并不总是这样做,考虑示例 auto i = 0l, f = 0.0;,它给出错误:

test.cpp: In function ‘int main()’:
test.cpp:4:5: error: inconsistent deduction for ‘auto’: ‘long int’ and then ‘double’
4 | auto i = 0l, f = 0.0;

如果我们编译您的程序并打印变量的类型 ( with this method ),我们将得到以下输出:

v1: std::initializer_list<int>, i1: int const*
v2: std::initializer_list<int>, i2: int const*

使用 gcc 版本 9.2.0,带有标志 -std=c++17 -pedantic -Wall -Wextra,没有任何警告或错误。

根据您对标准的评论,该程序格式不正确,并且标准 specifies除非另有说明(在本例中并非如此),否则应发出诊断消息(警告或错误)。因此我想说这是 gcc 中的一个错误。

a known bug .

关于c++ - 不同 C++ 编译器之间自动类型推导不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58855626/

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