[英]Constexpr, templates and array size
我想將模板參數傳遞給函數調用,返回值用作數組的大小即
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;
}
編譯器錯誤:
~ $ 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
知道怎么解決這個問題嗎?
在C ++ 11中, constexpr
函數只能包含一個return
語句(有關完整的詳細信息,請參見此處 ),因此myPow
函數不符合constexpr(因為它包含for
循環)。
您可以使用此元函數在編譯時計算整數冪:
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))));
}
如果要計算2^N
,可以鍵入:
pow<N>(2)
注1:這個元函數非常通用,也適用於負整數和浮點類型,所以你可以輸入: pow<-3>(3.14)
注2:模板中N>1
或N<0
的乘法在此處阻止無限遞歸,並在分支不相關時強制模板參數等於零。 這可以通過模板特化來完成,但這里使用的技術允許編寫單個函數。
在C ++ 11中, constexpr
函數非常受限制,並且您的代碼不符合限制(您不能聲明變量,改變本地狀態,也不能使用大多數形式的語句 - 包括循環)。 但是,C ++ 1y刪除了大多數限制,而Clang 3.3在其-std=c++1y
模式下接受原始代碼示例。
如果您需要代碼在C ++ 11模式下工作,您可以重寫它以避開constexpr
限制:
constexpr int myPow(int a, int b) {
return b ? a * myPow(a, b - 1) : 1;
}
編輯:轉到理查德史密斯的更聰明的答案。
根據您接受的答案,沒有必要使用元函數將myPow
算法實現為constexpr
myPow
函數。
您可以默認指數參數= 0然后:
constexpr int myPow(int a, int b = 0){
return b == 0 ? 1 : myPow(a,b - 1) * a;
}
如果你不喜歡默認那個參數,那么你可以在myPow
剛調用的constexpr
輔助中默認該參數,例如
namespace impl {
constexpr int myPow(int a, int b = 0){
return b == 0 ? 1 : myPow(a,b - 1) * a;
}
}
constexpr int myPow(int a, int b){
return impl::myPow(a,b);
}
如果你至少升級到gcc 4.7.2你甚至可以使用-std=c++11
來隱藏myPow
本身內的輔助,因為你可以在constexpr
函數體內定義類型:
constexpr int myPow(int a, int b){
struct _1 {
static constexpr int _2(int a, int b = 0) {
return b == 0 ? 1 : _2(a,b - 1) * a;
}
};
return _1::_2(a,b);
}
(雖然我認為嚴格來說這個緯度是C ++ 1y擴展)。
您可能希望調整Vincent的優越算法,使其不再是N
的元函數,但仍然是算術類型的通用算法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.