はじめに
C 17 では if constexpr が導入されましたキーワードを使用すると、コンパイル時の定数に基づいた条件付きコンパイルが可能になります。ただし、テンプレート化されていない関数で if constexpr を使用すると、予期しないエラーが発生する可能性があります。この記事では、これらの問題について検討し、解決策を示します。
コード例
次のコードを考えてみましょう:
<code class="cpp">#include <iostream> #include <type_traits> int main() { auto value = 100; if constexpr (std::is_pointer_v<decltype(value)>) std::cout << "Ptr to " << *value << std::endl; // Error else std::cout << "Ref to " << value << std::endl; }
コンパイル エラー
このコードは、if constexpr ステートメントが main 関数内にある場合にコンパイル エラーを生成します:
main.cpp:8:32: error: invalid type argument of unary ‘*’ (have ‘int’) std::cout << "Ptr to " << *value << std::endl;
説明
If constexpr のみこれは、コンパイラがコンパイル時に取得されない分岐のインスタンス化を回避できるため、テンプレート関数で機能します。この最適化は、テンプレートのメタプログラミングを効率的に行うために不可欠です。
テンプレート化されていない関数では、型が decltype によって推定される場合でも、constexpr が両方の分岐を評価します。これは、上記のコードのエラーは、if 分岐で int 値を逆参照しようとしたことが原因で発生していることを意味します。
解決策
この問題を解決するには、次のことができます。 if constexpr ステートメントをテンプレート関数に移動します。例:
<code class="cpp">template <typename T> void print(T value) { if constexpr (std::is_pointer_v<decltype(value)>) std::cout << "Ptr to " << *value << std::endl; else std::cout << "Ref to " << value << std::endl; } int main() { auto value = 100; print(value); }</code>
この変更されたコードは、期待される出力をコンパイルして出力します:
Ref to 100
以上が「if constexpr」が C 17 の非テンプレート関数でエラーを引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。