2017-07-26 93 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