2010-04-29 24 views
27

我想在類的內部定義一個常量,其中的值是最大可能的int值。事情是這樣的:在常量表達式中使用numeric_limits :: max()

class A 
{ 
    ... 
    static const int ERROR_VALUE = std::numeric_limits<int>::max(); 
    ... 
} 

這個聲明失敗,出現以下消息編譯:

numeric.cpp:8: error: 'std::numeric_limits::max()' cannot appear in a constant-expression numeric.cpp:8: error: a function call cannot appear in a constant-expression

我明白爲什麼這是行不通的,但兩件事情看起來怪我:

  1. 在我看來,在常量表達式中使用該值是自然的決定。爲什麼語言設計者決定使一個函數成爲一個函數,因此不允許這種用法?

  2. 中的規範要求18.2.1是

    For all members declared static const in the numeric_limits template, specializations shall define these values in such a way that they are usable as integral constant expressions.

    難道這是我應該能夠在我的情況下使用它,沒有它違背了錯誤消息?

謝謝。

+1

可以使用climits http://www.cplusplus.com/reference/clibrary/climits/ – Anycorn 2010-04-29 15:14:55

+1

@aaa:但'climits'對模板不會很好。 – UncleBens 2010-04-29 15:17:04

+2

@不幸的是。原則上可以在模板中定義,有些工作可行。或者boost integer_traits我認爲已經提供了它們:'integer_traits <> :: const_max/const_min' – Anycorn 2010-04-29 15:20:21

回答

16

雖然目前的標準在這裏缺乏支持,但對於整數類型Boost.IntegerTraits給出了編譯時間常量const_minconst_max

問題來自§9.4。2/4

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions.

需要注意的是它增加了:

The member shall still be defined in a name- space scope if it is used in the program and the namespace scope definition shall not contain an initializer.

正如其他人已經提到numeric_limit小號min()max()根本就不是整型常量表達式,即編譯時間常數。

13

你想:

#include <limits> 

struct A { 
static const int ERROR_VALUE; 
}; 

const int A::ERROR_VALUE = std::numeric_limits<int>::max(); 

放在一個標題的類/結構和定義在.cpp文件。

+2

可以像上面定義的ERR_VALUE一樣用作模板參數嗎? – Anycorn 2010-04-29 15:17:17

+2

課堂內外的初始化有什麼區別?我知道我可以用整數值初始化類內部的const。另外,我必須至少有一個這樣的類的實例,對吧?否則,編譯器可能決定不初始化它? – FireAphis 2010-04-29 15:18:19

+0

標註:在這裏沒有任何庫(可能是boost)重新定義這些值,以便它們可以用於metatemplate編程?在編譯期間讓它們在我們的處置是有意義的... – 2010-04-29 15:18:56

15

貌似有點缺陷的......

在C++ 0x中,numeric_limits將有標有constexpr一切,這意味着你將能夠使用min()max()的編譯時間常數。

+0

對於那些想知道的,明顯支持這個是在Visual Studio 2015中添加的。現在,如果我可以讓IT從2013年更新... – Phlucious 2017-05-25 16:07:33

4

它不矛盾,因爲max未定義static const。它只是一個靜態成員函數。函數不能是const,並且靜態成員函數也不能在最右邊附加const。

限制的雙重版本中還有一個double max(),在C++ 03中它不會說static double const max = ...。爲了保持一致,max()是限制模板的所有版本的功能。

現在已知max()不能被使用,因爲這是壞的,而C++ 0x已經通過使其成爲constexpr函數來解決它,從而允許您提出使用。

2
  • 我會盡量回答你就像我從你的問題理解爲:

1 - 如果你想在你的程序的靜態const int的同一個函數來初始化:

int Data() 
{ 
return rand(); 
} 

class A 
{ 
public : 
    static const int ee; 
}; 
const int A::ee=Data(); 

如果你想獲得最大和最小的編號爲給定的數據類型,然後使用這些定義 INT_MAX,在這部作品中對VS 2008

2- T_MIN,LONG_MAX等..

3-然而,如果你需要使用這些模板WRT類型,然後 硬編碼模板自己

template<> 
int MaxData() 
{ 
return INT_MAX; 
} 

template<> 
long MaxData() 
{ 
return LONG_MAX ; 
} 

,並呼籲他們像這樣

int y=MaxData<int>(); 

4-如果你只是處理二進制表示只有類型,然後使用此:

template <class T> 
T MaxData(){ 
    return ~(1<<((sizeof(T)*8)-1)); 
} 

template <class T> 
T MinData(){ 
    return (1<<((sizeof(T)*8)-1)); 
} 

希望這可以幫助你..

+0

而不是數值8,而是使用來自climits(limits.h)的CHAR_BIT宏。 – Aconcagua 2016-02-24 19:40:08