10

C++11 では次のようになりますconstexpr

constexpr int foo (int x) {
    return x + 1;
}

コンパイル時エラーfooの動的な値で呼び出しを行うことは可能ですか? xつまり、引数fooのみを渡すことができるようなものを作成したいと考えています。constexpr

4

4 に答える 4

9

それをメタ関数に置き換えます。

template <int x> struct foo { static constexpr int value = x + 1; };

使用法:

foo<12>::value
于 2013-07-15T20:54:22.157 に答える
3

残念ながら、constexpr絶対に必要な場合を除き、関数が、たとえ最も些細なものであっても、コンパイラによって評価されるという保証はありません。つまり、コンパイル時に値が必要な場所 (テンプレートなど) に表示されない限りです。コンパイル中にコンパイラに評価を実行させるには、次のようにします。

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 */

あまり良くない点は、マクロが必要なことですが、保証されたコンパイル時の評価ときれいなコードの両方が必要な場合、これは現在のところ避けられないようです。(私は間違っていることが証明されたいと思っています!)

于 2015-09-24T12:16:40.107 に答える
1

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

于 2014-09-18T08:02:13.053 に答える
1

はい、C++20 がこの種の問題のサポートを追加したため、純粋に慣用的な C++ で実行できるようになりました。関数に注釈を付けて、constevalコンパイル時に評価されていることを確認できます。https://en.cppreference.com/w/cpp/language/consteval

consteval int foo( int x ) {
    return x + 1;
}

int main( int argc, char *argv[] )
{
    return foo( argc ); // This will not compile
    return foo( 1 );    // This works
}

最も関連性の高い 3 つのコンパイラのこの godbolt.org デモも参照してください。

于 2021-12-16T12:52:40.390 に答える