問題描述
示例:
template<class T>
class Base {
public:
Base();
friend class T;
};
現在這不起作用...有沒有辦法做到這一點?
Now this doesn't work... Is there a way of doing this?
我實際上正在嘗試制作一個像這樣的通用類密封器:
I'm actually trying to make a general class sealer like this:
class ClassSealer {
private:
friend class Sealed;
ClassSealer() {}
};
class Sealed : private virtual ClassSealer
{
// ...
};
class FailsToDerive : public Sealed
{
// Cannot be instantiated
};
我在這個網站的某個地方找到了這個例子,但我找不到它......(這里)
I found this example on this site somewhere but I can't find it... (here)
我知道有其他方法可以做到這一點,但剛才我很好奇你是否真的可以做這樣的事情.
I know there are other ways of doing this but just now I'm curious if you actually can do something like this.
推薦答案
它在標準中被明確禁止,即使某些版本的 VisualStudio 允許它.
It is explicitly disallowed in the standard, even if some versions of VisualStudio do allow it.
C++ 標準 7.1.5.3 詳細類型說明符,第 2 段
C++ Standard 7.1.5.3 Elaborated type specifiers, paragraph 2
3.4.4 描述了如何在一個標識符中進行名稱查找.詳細類型說明符.如果標識符解析為一個類名或枚舉名,詳細類型說明符引入它進入聲明相同簡單類型說明符引入的方式它的類型名稱.如果標識符解析到 typedef 名稱或模板類型參數,詳細類型說明符是畸形.[注意:這意味著,在一個類模板中模板類型參數 T,聲明朋友類T;是畸形.]
3.4.4 describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name. If the identifier resolves to a typedef-name or a template type-parameter, the elaborated-type-specifier is ill-formed. [Note: this implies that, within a class template with a template type-parameter T, the declaration friend class T; is ill-formed. ]
我認為上面的代碼是一種密封(禁止擴展)類的模式.還有另一種解決方案,它不會真正阻止擴展,但會標記無意中從類中擴展.正如在 ADOBE 源庫中所見:
I recognize the code above as a pattern to seal (disallow the extension of) a class. There is another solution, that does not really block the extension but that will flag unadvertidly extending from the class. As seen in ADOBE Source Library:
namespace adobe { namespace implementation {
template <class T>
class final
{
protected:
final() {}
};
}}
#define ADOBE_FINAL( X ) private virtual adobe::implementation::final<T>
用法:
class Sealed : ADOBE_FINAL( Sealed )
{//...
};
雖然它允許擴展,如果你真的強迫它:
While it allows extension if you really force it:
class SealBreaker : public Sealed, ADOBE_FINAL( Sealed )
{
public:
SealBreaker() : adobe::implementation::final<Sealed>(), Sealed() {}
};
它會限制用戶誤操作.
編輯:
即將到來的 C++11 標準確實允許您與語法略有不同的類型參數成為朋友:
The upcoming C++11 standard does allow you to befriend a type argument with a slightly different syntax:
template <typename T>
class A {
// friend class T; // still incorrect: elaborate type specifier
friend T; // correct: simple specifier, note lack of "class"
};
這篇關于讓模板參數成為朋友?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!