我在嘗試實作一些 SFINAE 技巧時偶然發現了以下內容(我實際上試圖實作的目標是無關緊要的;我不想理解這種行為):
我定義了constexpr一個參考大小為 1 的陣列的函式,但我通過 lambda 呼叫指定了陣列大小:
constexpr bool f(const char(&)[ [](){return 1;}()]) {
return true;
}
( 在 lambda 之前是因為編譯器抱怨兩個連續的左括號。)
我添加了一個呼叫函式:
constexpr bool g() {
char x[1] = {};
return f(x);
}
這編譯得很好。
現在我模板化并實體化:
template<typename T>
constexpr bool f(const char(&)[ [](){return 1;}()]) {
return true;
}
constexpr bool g() {
char x[1] = {};
return f<int>(x);
}
這次我得到一個奇怪的編譯器錯誤:
ERROR: maps/suggest/indexer/nhr/nhr_flume_flags.cc:134:45 no matching function for call to 'f'
constexpr bool g() { char x[1] = {}; return f<int>(x); }
^~~~~~~
maps/suggest/indexer/nhr/nhr_flume_flags.cc:130:16 candidate function [with T = void] not viable: no known conversion from 'char[1]' to 'const char[ []() {
return 1;
}()]' for 1st argument
constexpr bool f(const char(&)[ [](){return 1;}()]) { return true; }
^
1 error generated.
為什么我會收到此錯誤?
我正在使用的命令是:/usr/lib/llvm-11/bin/clang -stdlib=libstdc -std=c 17 myprog.cc
編譯器的版本資訊是:
Debian clang version 11.1.0-4 build3
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm-11/bin
uj5u.com熱心網友回復:
為什么我會收到此錯誤?
/usr/lib/llvm-11/bin/clang -stdlib=libstdc -std=c 17 myprog.cc
在 C 17 中不允許在函式簽名中使用 lambda:
[expr.prim.lambda]
lambda 運算式是一個純右值,其結果物件稱為閉包物件。lambda 運算式不得出現在未計算的運算元中、模板引數中、別名宣告中、typedef 宣告中,或者在其函式體和默認引數之外的函式或函式模板的宣告中。[注意:目的是防止 lambdas 出現在簽名中。— end note ] [ 注意:閉包物件的行為類似于函式物件。——尾注]
該程式格式不正確。診斷資訊有改進的余地。不診斷非模板是編譯器錯誤。
使用常量很容易解決。也更容易閱讀:
constexpr inline auto s = [](){return 1;}();
template<typename T>
constexpr bool f(const char(&)[s])
由于提案 P0315,它應該在 C 20 中被允許,因為規則中突出顯示的部分已被洗掉。然而,Clang 仍然無法在 C 20 中編譯它,據我所知,這是一個錯誤。目前,Clang 對 P0315 的支持被列為“部分”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/453469.html
上一篇:我的rand()并沒有真正在C 中作業,特別是在VisualStudio2019中。我確實有“包括<time.h>和<stdlib.h>
下一篇:多行字串的識別符號預期錯誤
