[英]Weird type deduction using constexpr + auto as return and parameter type
我一直在玩編譯器優化和編譯器資源管理器,並注意到 g++ 9.3(本地測試)中的以下缺點。 該問題似乎在 g++ 10.1 中仍然存在(在編譯器資源管理器上測試)。 我正在使用
請注意以下代碼:
#include <iostream>
#include <iomanip>
constexpr auto fib( auto x )
{
if( x == 0 )
return 0;
else if( x == 1 )
return 1;
else
return fib( x - 1 ) + fib( x - 2 );
}
int main( int argc, char * argv[] )
{
std::cerr << std::setprecision(10) << fib( 47.l );
}
編譯器資源管理器鏈接在這里。
我知道如果我輸入 47,模板參數推導會推導出 function int foo( int x )
,但是即使我傳遞了一個長的雙精度字,這種情況仍然存在。
這會導致溢出。
為什么編譯器不能在編譯時推斷出我的返回類型應該是雙精度的? 我本來預計,由於 fib 被標記為 constexpr,並且我正在使用 -O3 進行編譯,因此即使我通過了 integer,g++ 也能夠通過意識到 fib 是指數的來推斷出需要雙精度數。
即使上述內容非常困難,為什么傳入一個長的雙字面量也不能解決問題? 我希望 function 能夠意識到 function 的第三個分支必須返回一個 long double,因此返回類型應該是 long double。
只有當 fib 更改為返回 0.l 和 1.l 時,編譯器才意識到需要 long double,如下所示:
constexpr auto fib( auto x )
{
if( x == 0 )
return 0.l;
else if( x == 1 )
return 1.l;
else
return fib( x - 1 ) + fib( x - 2 );
}
有趣的是,只將其中一個返回值更改為長雙精度字面值,如下所示:
if( x == 0 )
return 0.l;
else if( x == 1 )
return 1;
導致以下錯誤:
error: inconsistent deduction for auto return type: ‘long double’ and then ‘int’
這怎么會拋出錯誤,但第一個例子不會?
當您像這樣定義 function 時:
constexpr auto f(auto x)
{
return 42;
}
編譯器別無選擇,只能將返回類型推斷為int
,因為這是文字42
的類型。 如果您使用其他類型的參數調用f
並不重要:
f(42.l);
返回類型仍然是int
,盡管x
的類型是long double
。
但是,您可以明確要求返回類型與參數類型相同:
constexpr auto f(auto x) -> decltype(x)
{
return 42;
}
現在返回值將轉換為調用f
時使用的參數類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.