Clang 拒絕編譯以下代碼(godbolt),而 gcc 認為它沒有問題。Clang 錯誤訊息顯示在標記為 (2) 的行下方:
namespace // Overall anonymous namespace is required and cannot be removed.
{
template <typename T>
struct Friend;
namespace ns
{
class Secret
{
template <typename T>
friend struct Friend; // (1)
static void foo() {}
};
} // namespace ns
template <typename T>
struct Friend
{
void bar()
{
ns::Secret::foo(); // (2)
// Error at line (2):
// 'foo' is a private member of '(anonymous namespace)::ns::Secret'
}
};
} // anonymous namespace
我認為原因是第 (1) 行被視為新類模板的宣告,struct ns::Friend<T>而不是對::(anonymous namespace)::Friend<T>.
問題是:
- 誰是對的——clang 還是 gcc?
- 如果clang是對的,那么有沒有辦法讓它理解第(1)行沒有引入新的類模板,而是參考現有的?
uj5u.com熱心網友回復:
是的,你是對的,這只是friend struct Friend一個模板類的宣告::(anonymous namespace)::ns::Friend。兩個編譯器都是正確的,因為當您嘗試使用Friend<T>::bar()gcc 時也會抱怨訪問(clang 只是比 gcc 更早地檢查)
要在全域命名空間中指定類模板,您必須將其寫出來:
template <typename T>
friend struct ::Friend; // (1)
Friend這適用于 GCC,但 clang 似乎已損壞并且在全域命名空間中找不到。
這兩種解決方法似乎有效:
// Make the entire unnamed namespace an inline namespace
inline namespace
{
// ...
}
// Add an explicit using directive to help clang find Friend in `::`
namespace {
template<typename T>
struct Friend;
}
using ::Friend;
namespace {
namespace ns {
// ...
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/519915.html
標籤:C 模板C 17朋友
上一篇:wso2為用戶操作啟用通知
