ホームページ >バックエンド開発 >C++ >「if constexpr」が C 17 の非テンプレート関数でエラーを引き起こすのはなぜですか?

「if constexpr」が C 17 の非テンプレート関数でエラーを引き起こすのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-06 03:58:02860ブラウズ

Why does

C 17 の非テンプレート関数の「If constexpr」エラー

はじめに

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。