2012-07-06 55 views
3

我在想,如果有可能做到以下幾點:C++:有沒有辦法創建模板命名空間?

template <typename T> 
namespace basic_foo { 
    struct str { 
     T value; 
    }; 
} 

basic_foo<char>::str s1; 
namespace foo = basic_foo<char>; 
foo::str s2; 

是否有可能做到這一點在任何C++編譯器?
有沒有工作來實現這一點?
我認爲這將是一個很好的補充語言。

在此先感謝。

+0

爲什麼你不能在命名空間內創建一個模板化的結構 – Wug 2012-07-06 16:45:54

+0

這將是一個很好的功能。 – 2012-07-06 16:47:43

+0

@Wug:Koenig查找 – 2012-07-06 16:48:59

回答

10

不,您不能定義名稱空間模板。你可以,但是,實現幾乎正是你想要的(僅稍微不同的語法),通過使basic_foo類模板:

template <typename T> 
struct basic_foo { 
    struct str { 
     T value; 
    }; 
}; 

basic_foo<char>::str s1; 
typedef basic_foo<char> foo; 
foo::str s2; 
+0

關閉,但沒有參數相關查找。 – 2012-07-06 16:50:34

+0

@ BenVoigt:'basic_foo :: str'可以聲明朋友,這些朋友將通過ADL發現。 (你是對的,雖然它不是完全相同的。) – 2012-07-06 16:52:11

+0

是的,但在'basic_foo '內定義的函數不會被ADL找到......如果'basic_foo'是一個真實的名稱空間,它們就會是。你可以把它們放在父命名空間中,但是你失去了對模板參數的訪問,並且必須重新指定它們。 – 2012-07-06 16:53:06

5

沒有,但你可以用模板結構:

template<typename T> 
struct basic_foo 
{ 
    struct str 
    { 
     T value; 
    }; 
}; 

typedef basic_foo<char> foo; 
foo::str s1; 

你也可以使用class而不是struct,但在這種情況下您必須記住約public:

1

不是。它不可能,命名空間模板是不真實的,但是你可以創建類模板。

0

其他答案解釋瞭如何做它看起來像你可能想要的。但是,聽起來你對命名空間的內容有不同的想法,而不是真正爲其設計的。

命名空間解決了兩個不相關的C++代碼庫可以相互通信的問題。 C沒有名稱空間,因此結果更加冗長。嘗試在C中使用第三方庫,如openssl或oauth。您會發現很多這樣的函數調用:

openssl_create 
openssl_connect 

等等。這真的非常重要。因爲很可能我想寫一個叫做connect的函數。我使用的ZMQ庫的作者也是如此。等等。這是一個主要的痛苦,有兩個同名的函數試圖在同一個地方被調用...

命名空間純粹是一個軟件工程構造,而不是編程。它可以讓前綴openssl_簡單地變成命名空間,因此類似上面的代碼可以更自由地混合。爲什麼不命名空間衝突?這就是軟件工程變得更加人性化和社交化的地方,因爲全球編程界必須確保這一切不會發生。通常外部命名空間通常是公司;我猜想所有Google的內部代碼都在命名空間Google中。 Java通過推廣互聯網域名的命名包(例如命名空間)的約定來解決這個問題,該互聯網域名可能是不可抵觸的真實世界實體,例如,谷歌代碼應該存在於包com.google...

我還應該注意到,在一個組織中,在應用程序,產品或團隊級別使用命名空間 - 例如, Google Drive在Google Mail的某個地方可能有一個「上傳」的功能,而這些團隊通常不會彼此交談......但仍然需要編寫混合代碼。 這就是命名空間的作用。沒有更多,沒有更多。

相關問題