我想知道如果c + + 11/c + + 14會/已經支持像vector<auto>
? 如果沒有,是否有任何理由?是否/會C++ 11/14支持類似於矢量<auto>
回答
它不直接支持,並且不能立即清楚你想要它做什麼。
評論已經提到了創建異構集合的幾種可能性(如Boost any
和variant
類)。我希望這不是你以後的樣子,因爲異構集合與C++很差,因此使用它們很難看,也很笨拙。我想有些情況下這些確實是最好的選擇,但至少在我的經驗中,這些情況相當罕見。你可能想要的另一種可能的解釋是一個向量(就像一般的auto
)只有一種類型,但是這種類型是從初始值設定項中推導出來的,所以如果你初始化了一些int
的向量, d得到一個vector<int>
,如果你從一些字符串初始化它,你會得到一個vector<string>
,依此類推。雖然語言不直接支持,但至少在某種程度上很容易模擬它。模板類不能/不會推導模板參數,但模板函數 do/can。因此,我們可以創建一個小函數模板來獲取一些初始化器,推導出它們的類型,並返回該類型的向量。例如:
template <class T>
std::vector<T> make_vector(std::initializer_list<T> init) {
return std::vector<T>(init);
}
這將返回vector<T>
(與T
從數據在初始化列表中的類型推斷)一個,所以你可以做這樣的事情:
auto a = make_vector({ 1, 2, 3, 4 }); // a -> vector<int>
auto b = make_vector({ 1.0, 2.0, 3.0 }); // b -> vector<double>
auto c = make_vector({ "1"s, "2"s, "3"s }); // c -> vector<std::string>
這最後一個要求用戶在C++ 14中是新定義的文字操作符(許多編譯器現在還不支持)。其餘的應該與C++ 11一樣好。
也有一些討論(和N3602中的一個建議)添加一個功能(可能是C++ 17),您可以在其中定義類似上面的make_vector
,但是像模板化構造函數爲班級。這將讓你使用參數推導的構造推斷該類作爲一個整體的模板參數,所以你可以這樣做:
X x(1); // deduces as X<int>
X x(2.0) // deduces as X<double>
警告,雖然:這已經被提出,但未被接受。它可能(容易)從不被接受 - 即使它是,它可能會發生重大變化之前發生。
我相信你想要的提議是[N3602] (http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2013/n3602.html),目前我認爲這不會發生。 – 2014-09-30 17:09:12
@dyp:經過一番思考(還有一點點閱讀)後,我認爲你是對的 - 至少在這種情況下(也許總的來說,儘管我不確定)通過價值無疑是最有意義的(而我已經相應編輯)。 – 2014-09-30 18:28:35
@JonathanWakely:感謝您的鏈接 - 是的,那是我正在考慮的那個(我已經編輯了答案的鏈接,以及更強硬的措辭警告,它可能永遠不會發生)。 – 2014-09-30 18:33:55
不,不在C++ 11或C++ 14中,它們已經完成併發布。
但是有可能vector<auto>
和類似的東西tuple<auto...>
將作爲Concepts工作的一部分在C++ 17中。
它遵循很自然地從以下事實std::vector<T>
可以在功能模板和類模板偏特被用於其中T
是模板參數,並且還從一個事實,即多晶型的lambda允許auto
作爲函數參數類型(這是速記對於具有推導參數的函數模板)。
的概念TS允許被宣佈爲「通用功能」,如:
auto func(auto arg);
既然你可以有一個函數模板是這樣的:
template<typename T>
auto func(std::vector<T> v);
是有意義的延長通用函數語法允許:
auto func(std::vector<auto> v);
一旦你允許它在函數聲明中,它也應該是可以允許它在變量聲明:
std::vector<auto> v = function_returning_vector_of_something();
的原因,它是不是在C++ 11是auto
是新的,而且它會一直過於雄心勃勃,試圖讓它做太多。在C++中,14個多態lambda表達式是新的,並且再次擴大auto
的用法本來就是雄心勃勃的。
對於C++ 17,我們在實際代碼中使用auto
有更多的經驗,編譯器編寫者熟悉實現它,並且知道什麼可能沒有太多的努力。
你是說在C++ 17中,編譯器能夠從initializer_list中爲'std :: vector
我不是說它能夠做任何事情,現在知道它還爲時過早。這個例子的重點不在於初始化列表,而是使用'auto',所以我改變了這個例子。 – 2014-10-01 10:19:07
A boost::any
可以存儲任何可以複製的類型的實例,這是一個很多類型。
爲了從您的any
中獲取數據,您必須知道存儲在其中的確切類型。
編寫一個簡單的any
並不難:
#include <memory>
#include <utility>
struct any_internal {
virtual any_internal* clone() const = 0;
virtual ~any_internal() {};
};
template<class T>
struct any_details;
class any {
std::unique_ptr<any_internal> internal;
public:
any() = default;
any(any &&) = default;
any(any const&& o):any(o) {}
any(any & o):any(const_cast<any const&>(o)) {}
any& operator=(any &&) = default;
any& operator=(any const&& o) { return this->operator=(o); };
any& operator=(any & o) { return this->operator=(const_cast<any const&>(o)); };
any(any const& o):internal(o.internal?o.internal->clone():nullptr) {}
any& operator=(any const& o) {
any tmp(o);
using std::swap;
swap(internal, tmp.internal);
return *this;
}
template<class U>
void reset(U&& o);
template<class U, class... Args>
void emplace(Args&&... args);
template<class U>
any(U&& o);
template<class U>
any& operator=(U&& o);
template<class T> T* get();
template<class T> T const* get() const;
template<class T> T* fast_get();
template<class T> T const* fast_get() const;
explicit operator bool() const { return internal!=nullptr; }
};
template<class T>
struct any_details : any_internal {
T t;
template<class...Args>
any_details(Args&&... args):t(std::forward<Args>(args)...) {}
any_internal* clone() const override { return new any_details<T>{t}; }
};
template<class U, class... Args>
void any::emplace(Args&&... args) {
internal.reset(new any_details<U>(std::forward<Args>(args)...));
}
template<class U>
void any::reset(U&& o) {
emplace<typename std::decay<U>::type>(std::forward<U>(o));
}
template<class U>
any::any(U&& o) {
reset(std::forward<U>(o));
}
template<class U>
any& any::operator=(U&& o) {
reset(std::forward<U>(o));
return *this;
}
template<class T> T* any::get() {
auto* r = dynamic_cast< any_details<T>* >(internal.get());
if (r) return &r->t;
return nullptr;
}
template<class T> T const* any::get() const {
auto* r = dynamic_cast< any_details<T>* >(internal.get());
if (r) return &r->t;
return nullptr;
}
template<class T> T* any::fast_get() {
auto* r = static_cast< any_details<T>* >(internal.get());
if (r) return &r->t;
return nullptr;
}
template<class T> T const* any::fast_get() const {
auto* r = static_cast< any_details<T>* >(internal.get());
if (r) return &r->t;
return nullptr;
}
和std::vector<any>
行爲很像你可能要一個std::vector<auto>
做。
通過小緩衝區優化可以實現提高效率(即,如果t
很小,而不是使用堆,則將T
存儲在any
之內)。
你可能也想從fast_get
,其中get
做了dynamic_cast
和fast_get
做了static_cast
,再次拆分效率get
。 (當你知道確定的時候,你可以fast_get
)
基本上這是一個gussied up void*
。
爲什麼'任何const &&'和'任何&'拷貝ctors? – dyp 2014-09-30 22:29:11
'swap(internal,tmp.internal);'或'internal = std :: move(tmp.internal);' – dyp 2014-09-30 22:43:53
@dyp我有一個通用拷貝ctor&賦值,我明確表示不會在rhs時調用它是一個'任何'。是的,一個'移動'也可以工作:我在做copy-swap,然後懶得執行'void swap(any&,any&)',因爲我注意到它是2行。感謝修復 - 已經寫好了。 – Yakk 2014-09-30 23:02:23
- 1. Objective-C是否支持類變量?
- 2. IE是否支持indexedDB,WebSQL或類似於SQLite的數據庫?
- 3. TestNG是否支持類似於JUnit4的@Rule?
- 4. Android是否支持佈局繼承(類似於Django模板)?
- 5. 支持C#的矢量機器庫#
- 6. Java是否具有類似於C#的事件的本機支持?
- 7. Eclipse是否支持C/C++?
- 8. 如何覆蓋類似於矢量的C++類
- 9. Scala類似於SQL的支持,如LINQ
- 10. 爲什麼msgpack-C++在我的情況下不支持矢量<float>或矢量<double>?
- 11. .NET Reporting Services是否支持矢量圖形?
- 12. WebAnimations是否支持矢量形狀轉換
- 13. ColdFusion是否支持常量?
- 14. C++是否支持字符串類型的常量數組?
- 15. Objective-C是否支持#elifdef?
- 16. ASP.NET是否支持C++?
- 17. OFBIZ是否支持C#?
- 18. GCC是否支持C++ AMP
- 19. C++傳遞一個矢量<矢量<STRUCT>>用於修改
- 20. 類似於矢量的數據類型,但已排序
- 21. JavaScript是否支持<=運算符?
- 22. ROWLEX是否本機支持IEnumerable <>?
- 23. Google BigQuery是否支持ARRAY <STRING>?
- 24. 是否有可能基於矢量<double>
- 25. 是否有類似於可用於C#消息框的橫線(即<hr>)?
- 26. IndexedDB是否支持類似SQL的事務?
- 27. SQL Server是否支持類似Oracle的WITH子句?
- 28. Groovy是否支持類似Ruby模塊的內容?
- 29. IntelliJ是否支持類似VS調試器展示器?
- 30. 是否有任何類似Querydsl支持Solr
它將如何使用? – Cameron 2014-09-30 13:47:36
也許在C++ 999中,你可以'push_back'任何東西到'vector'中。 :P – herohuyongtao 2014-09-30 13:48:55
@cameron,用它我們可以寫更多通用的代碼 – 2014-09-30 13:56:45