所以我這里有一些用 gcc、clang 和 msvc 編譯的代碼:
#include <cstdio>
#include <type_traits>
struct c_class;
template <class T> struct holder { friend auto adl_lookup(holder<T>); };
template <class C, class T> struct lookup {
friend auto adl_lookup(holder<T>) { return holder<C>{}; }
};
struct cpp_class : lookup<cpp_class, c_class *> {
cpp_class() {}
};
int main() {
static_assert(std::is_same<holder<cpp_class>,
decltype(adl_lookup(holder<c_class *>{}))>{},
"Failed");
}
原因adl_lookup是在lookup類而不是holder類中定義,以便您可以在從 CRTP 類繼承時c_class進行“反向”查找。所以朋友功能不能移動到類。cpp_classlookup<cpp_class, c_class *>holder
但是,在 gcc 上,我收到有關非模板友元函式的警告:
<source>:9:37: warning: friend declaration 'auto adl_lookup(holder<T>)' declares a non-template function [-Wnon-template-friend]
9 | friend auto adl_lookup(holder<T>);
| ^
<source>:9:37: note: (if this is not what you intended, make sure the function template has already been declared and add '<>' after the function name here)
如果我嘗試通過前向宣告函式然后使用來解決此問題<>,它不會使用 gcc 或 msvc 編譯(盡管它確實使用 clang 編譯):
#include <cstdio>
#include <type_traits>
struct c_class;
template <class T> struct holder;
template <class T> auto adl_lookup(const holder<T> &);
template <class T> struct holder {};
template <class C, class T> struct lookup {
friend auto adl_lookup<>(const holder<T> &) { return holder<C>{}; }
};
struct cpp_class : lookup<cpp_class, c_class *> {
cpp_class() {}
};
int main() {
static_assert(std::is_same<holder<cpp_class>,
decltype(adl_lookup(holder<c_class *>{}))>{},
"Failed");
}
我在這里(在兩個片段中)使用符合標準的 C 嗎?是否有理由擔心 gcc 關于非模板朋友的警告,還是我可以安全忽略的誤報?
uj5u.com熱心網友回復:
第二個片段格式錯誤,因為friend宣告不能是模板特化的定義。接受此問題的開放式 clang 錯誤報告在這里。
第一個對我來說似乎有效。
GCC 的警告很煩人,因為在這里定義一個非模板函式作為朋友是你想要做的。不幸的是,我認為沒有任何方法可以在代碼中表明這確實是您想要做的,但是您可以使用-Wno-non-template-friend. 根據檔案,由于歷史原因,它存在于識別語法具有不同含義的 pre-ISO-C 兼容性問題。
您應該知道,使用這種朋友注入來啟用有狀態元編程的能力可能被認為是該語言的意外功能,并且可能(我不知道)在未來的某個時候會受到限制,請參閱這個問題。
uj5u.com熱心網友回復:
這是一個常見的錯誤,即使代碼是合法的,也可以if (var = foo())使用。if (var == foo())
而添加額外的父母允許“通知”編譯器意圖是=/==案例中所期望的。
if ((var = foo()))
沒有任何技巧可以告訴您它確實是您要使用的非模板函式。
對于給定的編譯器,仍有傳統#pragma方法可以在特定區域禁用警告(請參閱how-to-disable-gcc-warnings-for-a-few-lines-of-code)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/433971.html
下一篇:帶有自動模板引數的部分模板特化
