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

Barbara Streisand
リリース: 2024-11-06 03:58:02
オリジナル
768 人が閲覧しました

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!