2016-11-15 139 views
2

我趕上試圖與consexpr裝飾時錯誤「constexpr功能......不是迴歸語句的身體」:最小/最大/步驟的功能和

$ g++ -std=c++11 test.cxx -o test.exe 
test.cxx: In instantiation of ‘static constexpr unsigned int MinMaxStep<min, max 
, step>::ValidValue(unsigned int) [with unsigned int min = 10u; unsigned int max 
= 100u; unsigned int step = 10u]’: 
test.cxx:22:40: required from here 
test.cxx:16:5: error: body of constexpr function ‘static constexpr unsigned int 
MinMaxStep<min, max, step>::ValidValue(unsigned int) [with unsigned int min = 10 
u; unsigned int max = 100u; unsigned int step = 10u]’ not a return-statement 
    } 
    ^

所有使用的值問題函數是模板參數。文件保存後,值不會更改。

難道無法將其表示爲constexpr函數嗎?

如果我做錯了什麼,那它是什麼?如何將ValidVaue修改爲constexpr函數?


$ cat -n test.cxx 
1 #include <string> 
2 #include <iostream> 
3 
4 template <unsigned int min, unsigned int max, unsigned int step> 
5 class MinMaxStep 
6 { 
7 public: 
8  static constexpr unsigned int Min() { return min; } 
9  static constexpr unsigned int Max() { return max; } 
10  static constexpr unsigned int Step() { return step; } 
11  static constexpr unsigned int ValidValue(unsigned int v) 
12  { 
13   if (v <= min) { return min; } 
14   else if (v >= max) { return max; } 
15   return (v+step-1) - ((v+step-1)%step); 
16  } 
17 }; 
18 
19 int main (int argc, char* argv[]) 
20 { 
21  MinMaxStep<10, 100, 10> mms; 
22  unsigned int x = mms.ValidValue (18); 
23  std::cout << "value " << x << std::endl; 
24 
25  return 0; 
26 } 
+2

'return v <= min? min:(v> = max?max:((v + step-1) - ((v + step-1)%step)));' –

+0

一個帶三元運算符的返回語句被接受。你知道它是否被所有主要編譯器(Clang,Comeau,GCC,ICC,MSVC和SunCC)接受?他們中的任何一個都有你知道的一半的實現嗎? – jww

回答

5

constexpr函數的規則是在C++ 11非常嚴格。例如,可能有只有 a return聲明,沒有別的。規則在C++ 14中大大放寬。

參見例如this constexpr reference欲瞭解更多信息。

有兩種方法可以解決您的問題:最簡單的方法是改用C++ 14(將編譯器標誌更改爲使用-std=c++14)。另一種解決方案是使用三元運算符來重構您的ValidValue函數,使其只有一條語句,即return語句。

+0

大聲笑... C++ 14是不可能的。有時我們生活在一個特別的地獄中。通過今天發現的任何東西,我們都支持Fedora 1上的GCC 3和Windows 2000上的Visual Studio .Net。 – jww

+1

@jww:然而'constexpr'仍然是您的選擇? o_O – ildjarn

+0

@ildjarn - 是的,'constxpr',像其他關鍵字一樣,如'noexcept'或'alignas',可以在宏中抽象出來(https://github.com/weidai11/cryptopp/blob/master/ config.h中的#L923)。我不能讓一箇舊的編譯器接受新的標誌:) – jww