ホームページ  >  記事  >  バックエンド開発  >  C 17 の非テンプレート関数で「if constexpr」が機能しないのはなぜですか?

C 17 の非テンプレート関数で「if constexpr」が機能しないのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-06 19:01:03494ブラウズ

Why Doesn't `if constexpr` Work in Non-Templated Functions in C  17?

if constexpr が C 17 の非テンプレート関数で期待どおりに動作しない

C 17 では、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;
}</code>

このコードをコンパイルすると、エラーが発生します。 if constexpr ステートメント内の 'value' を逆参照しようとしている行で発生します。これは、constexpr がテンプレート化されていない関数でサポートされていないためです。

なぜテンプレートだけなのか?

この動作は仕様によるものです。 constexpr が特定の特殊化に基づいた無効なテンプレート コードのインスタンス化を防ぐことを目的としている場合。提供されている例では、テンプレート化されていない関数は、std::is_pointer_v を使用して 'value' がポインターであるかどうかをチェックします。ただし、条件が false の場合でも、コンパイラは整数 'value' を逆参照しようとしますが、これは無効です。

解決策

非テンプレート化されたコンテキストを使用する場合は、コードをテンプレート関数でラップするか、コンパイル時に異なる動作をするマクロを使用することを検討してください。例:

<code class="cpp">#include <iostream>
#include <type_traits>

template<typename T>
void print(T value)
{
  if constexpr (std::is_pointer_v<T>)
    std::cout << "Ptr to " << *value << std::endl;
  else
    std::cout << "Ref to " << value << std::endl;
}

int main()
{
  auto n = 1000;
  print(n);

  int *ptr = &n;
  print(ptr);
}</code>

この場合、print 関数はテンプレート化されているため、constexpr の動作はテンプレート パラメーターに基づいて正しく適用されます。

以上がC 17 の非テンプレート関数で「if constexpr」が機能しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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