在C++ 11我們得到constexpr
:強制編譯時constexpr
constexpr int foo (int x) {
return x + 1;
}
是否有可能使foo
調用與x
編譯時錯誤動態值?也就是說,我想創建一個foo
,這樣只能通過constexpr
參數。
在C++ 11我們得到constexpr
:強制編譯時constexpr
constexpr int foo (int x) {
return x + 1;
}
是否有可能使foo
調用與x
編譯時錯誤動態值?也就是說,我想創建一個foo
,這樣只能通過constexpr
參數。
我會用static_assert
如本例所示
#include<iostream>
constexpr int foo(int x) {
return x+1;
}
int main() {
// Works since its static
std::cout << foo(2) << std::endl;
static_assert(foo(2) || foo(2) == 0, "Not Static");
// Throws an compile error
int in = 3;
std::cout << foo(in) << std::endl;
static_assert(foo(in) || foo(in) == 0, "Not Static");
}
更多的相關信息:http://en.cppreference.com/w/cpp/language/static_assert
我沒有帶'constexpr'的編譯器ATM,但是這個想法是否延伸到將'static_assert'直接放到'foo'中?例如。 'constexpr int foo(int x){static_assert(x == x,「Not Static」);返回x + 1; }' –
@ThomasEding。你可以,但是你會失去使用與運行時評估函數相同功能的靈活性。由於在編譯時檢查了'static_assert',它也不會影響運行時。 –
不幸的是,除非絕對必要,否則無法保證編譯器會評估函數,即使是最微不足道的函數。也就是說,除非它出現在編譯時需要它的值的地方,例如在模板中。爲了強制編譯器在編譯過程中做了評價,你可以做到以下幾點:
constexpr int foo_implementation (int x) {
return x + 1;
}
#define foo(x) std::integral_constant<int, foo_implementation(x)>::value
,然後在你的代碼像往常一樣
使用foo
int f = foo(123);
這種方法的好處是,它保證了編譯時的評價,如果你通過一個運行時變量foo
,你會得到一個編譯錯誤:
int a = 2;
int f = foo(a); /* Error: invalid template argument for 'std::integral_constant',
expected compile-time constant expression */
不那麼好的一點是它需要一個宏,但如果你希望保證編譯時評估和漂亮的代碼,這似乎是不可避免的。 (我很想被證明是錯誤的!)
你可以隨時把它變成一個函數模板:'template int foo(){return x + 1; }' –
請注意,'constexpr'被部分調用來抵消所有您將在答案中看到的語法解決方法。 (#) – rubenvb
'#define foo(N)foo()'看起來可行。 –