2016-11-15 129 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