I would like to pass template argument to function call and the return value use as size of an array ie
constexpr int myPow(int a, int b){
int result = 1;
for(int i=0;i<b;i++)
result *= a;
return result;
}
template <int N>
class testClass{
public:
testClass(){}
int array[myPow(2,N)];
};
int main(){
testClass<3> A;
return 0;
}
compiler errors:
~ $ g++-4.6 test.cpp -std=gnu++0x
test.cpp: In function ‘constexpr int myPow(int, int)’:
test.cpp:6:1: error: body of constexpr function ‘constexpr int myPow(int, int)’ not a return-statement
test.cpp: At global scope:
test.cpp:12:23: error: array bound is not an integer constant before ‘]’ token
Any idea how to get around this?
In C++11, a constexpr
function can only contain a return
statement (see here for the full details), so your myPow
function is not constexpr-compliant (because it contains a for
loop).
You can use this metafunction to compute the integer power at compile-time:
template <int N, typename Type>
constexpr Type pow(const Type& x)
{
return (N > 1) ? (x*pow<(N-1)*(N > 1)>(x))
: ((N < 0) ? (static_cast<Type>(1)/pow<(-N)*(N < 0)>(x))
: ((N == 1) ? (x)
: (static_cast<Type>(1))));
}
If you want to compute 2^N
, you can type:
pow<N>(2)
Note 1: this metafunction is very generic and also work for negative integers and floating-point types, so you can type : pow<-3>(3.14)
Note 2: the multiplication by N>1
or N<0
in the template are here to block infinite recursivity and force the template parameter to be equal to zero when the branch is not relevant. This could be done with template specialization, but the technique used here allow to write a single function.
In C++11, constexpr
functions are quite restricted, and your code doesn't comply with the restrictions (you can't declare variables, mutate local state, nor use most forms of statements -- including loops). However, C++1y removes most of the restrictions, and Clang 3.3 accepts your original code sample in its -std=c++1y
mode.
If you need the code to work in C++11 mode, you can rewrite it to sidestep the constexpr
restrictions:
constexpr int myPow(int a, int b) {
return b ? a * myPow(a, b - 1) : 1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With