2017-07-26 44 views
0

假設someAtomic是一個具有整體基礎類型的std :: atomic,如atomic_uint16_t。我不想擔任哪種整數類型,然而,在特定的代碼,所以我想要的東西來完成;下面,現在不能編譯:原子類型的numeric_limits

if (newVal > numeric_limits<decltype(someAtomic)>::max()) throw "newVal too large"; 
else someAtomic.store(newVal, memory_order_release); 

看起來至少在VC++ 2015年,對於原子類型沒有numeric_limits專業化,即使它們的基礎類型確實有這樣的專業化。處理這個問題的最好方法是什麼?

回答

4
template<class T> 
struct my_numeric_limits : std::numeric_limits<T>{}; 

template<class T> 
struct my_numeric_limits<std::atomic<T>> : my_numeric_limits<T>{}; 

然後你可以使用my_numeric_limits<SomeAtomic>::max()

這不太可能違反(含糊不清)部分標準,而不是添加專門化到std::numeric_limits而不依賴於用戶提供的類型。在C++ 11中,有些需求專門針對「用戶定義的類型」,如果std::atomic<int>是用戶定義的,我不確定這是否已經解決。我看到了一個修復建議,但是我不確定它是否到達任何地方。

無論如何,這遵循最少驚喜的原則,並且同樣有效。在std命名空間中的事情應該只在替代方案不切實際時才能完成。

出錯了,你的代碼突然變形,不需要診斷。檢查你的代碼的人是正確的害怕。修改你的代碼的人不得不搞砸。 my_numeric_limits是健壯,安全,並抵制錯誤。

2

C++標準允許(並鼓勵)將專業化添加到std::numeric_limits,您可以做到這一點。

#include <limits> 
#include <atomic> 
#include <iostream> 

template<typename T> 
class std::numeric_limits<std::atomic<T>> : public std::numeric_limits<T> {}; 

int main() 
{ 
    std::cout << std::numeric_limits<std::atomic<int>>::max(); 
} 
+1

我不確定是否允許您將標準模板與標準庫中的類型專用 – KABoissonneault

+2

如果允許,我會非常驚訝。你可以備份你的聲明嗎? – hvd