如果我在建立一個庫,我假設圖書館的某些「客戶」可能只使用C++ 11,那麼我可以使用C++ 14爲其內部編譯庫本身嗎?
是的,一般來說應該是可以的。
我正是爲GCC執行Filesystem TS做的。 <experimental/filesystem>
頭文件採用純C++ 11編寫,可由C++ 11客戶端包含,但libstdc++fs.a
中的實現採用C++ 14編寫。
是否存在與C++ 11相比的API/ABI /鏈接兼容性問題?
有C++ 11和C++ 14之間沒有改變該要求實現打破它們的鏈接時的相容性。那並不意味着的實現不會打破它,但它們並不是必需的。
對於GCC我相信C++ 11和C++ 14完全是API和ABI兼容的,除了下面提到的constexpr
和size-deallocation問題。
只要我在公共API中避免某些新特性,是否可以安全地使用C++ 14來實現和構建庫,如果是這樣,我必須避免什麼?
它取決於你的編譯器,但理論上它是可能的。
明顯地避免任何在C++ 11中無效的C++ 14語言特性(例如函數返回類型推導或帶有參數auto
的泛型lambdas或可變模板)以及任何C++ 14庫實體,如std::make_unique
,std::integer_sequence, or
std :: shared_timed_mutex`。
C++ 14中幾乎所有變化的列表可以在SD-6中找到。
有一點需要注意的是,非靜態的constexpr
成員函數的含義在C++ 11和C++ 14之間改變了。在C++ 11中,此成員函數是const
:
struct X {
constexpr int foo();
};
在C++ 14中,它是非常量的。能夠同時與C++ 11和C++ 14兼容的,你應該明確地限定它爲const
:
struct X {
constexpr int foo() const;
};
這意味着在這兩個C++ 11和C++ 14的同樣的事情。
另一個需要注意的是,在C++ 11和C++ 14這個操作符意味着不同的東西:
void operator delete(void*, std::size_t);
如果C++ 11的客戶端的代碼定義函數,那麼你的庫C++編譯14 可能最終調用它而不是通常的operator delete(void*)
,這可能會做錯誤的事情。這是可能非常罕見,並不是真正的代碼中的問題,但它是可能的。 G ++和Clang允許您使用-fno-sized-deallocation
編譯C++ 14代碼以禁用新功能,以便您的C++ 14庫代碼永遠不會調用operator delete
的該版本。
只要客戶端使用相同的編譯器版本,即使他們不使用C++ 14功能,也可以使其工作。如果他們使用不同版本的編譯器,那麼在使用Visual Studio時肯定無法工作。 –
你的確切編譯器是什麼?什麼編譯器會使用它? – Yakk
OSX上的Clang; Linux上的Clang或gcc; Windows上的MSVS。爲了爭論,我們假設庫和應用程序都使用相同的編譯器和相同的版本,所以我的問題歸結爲我是否可以使用-std = C++ 14作爲庫,而-std = c + +11在應用程序中,以及我需要記住公共API使其工作的具體事項。 –