2

n-any ブール型ORランタイム関数がありますany_run

#include <assert.h>

bool any_run() { return false; }

template <typename... B>
bool any_run(bool a, B... b)
{
    assert(a);
    return a || any_run(b...);
}

コンパイル時のアナログと同様にany_comp

#include <type_traits>

template <bool E>
using expr = std::integral_constant <bool, E>;

using _true  = expr <true>;
using _false = expr <false>;

template <typename... A>
struct any_comp : public _false { };

template <typename A, typename... B>
struct any_comp <A, B...> : public expr <A() || any_comp <B...>()>
{
    static_assert(A(), "");
};

どちらにも、最初の引数が true であることを確認するためのアサーション (それぞれ実行時またはコンパイル時) が含まれています。

次の入力を与える

int main()
{
    any_run   (true,  false,  false);
    any_comp <_true, _false, _false>();
}

実行時のアサーションは決して失敗しませんが、コンパイル時のアサーションは失敗します。これは、any_run(false, false)呼び出されることはありany_comp <_false, _false>ませんが、インスタンス化されることを意味します。

A() || any_comp <B...>()

をインスタンス化せずにtrueifと評価できます。A() == trueany_comp <B...>

私の質問は、この実験とその結論が有効かどうか、そして標準がそれについて何と言うかということです.

結論が有効である場合、コンパイルを高速化するために、いくつかのコンパイル時関数をより慎重に (より特殊化して) 再実装する必要があるため、これは重要です。

4

1 に答える 1

3

短絡は、 の実行時レベルでのみ機能します||。コンパイル時には、次のようなものが必要です。

#include <type_traits>

template <typename T, typename U>
struct integral_or : U { };

template <typename U>
struct integral_or <std::true_type, U> : std::true_type { };

template <typename... A>
struct any_comp : std::false_type { };

template <typename A, typename... B>
struct any_comp <A, B...> : integral_or <A, any_comp <B...>>
{
    static_assert(A(), "");
};

int main()
{
    any_comp <std::true_type, std::false_type, std::false_type>();
}
于 2013-09-21T11:52:28.300 に答える