ホームページ  >  記事  >  バックエンド開発  >  \"Timer()\" は関数ですか、それともオブジェクトですか? C の「最も厄介な解析」を理解する 11.

\"Timer()\" は関数ですか、それともオブジェクトですか? C の「最も厄介な解析」を理解する 11.

Barbara Streisand
Barbara Streisandオリジナル
2024-11-02 15:33:29715ブラウズ

Is

最も厄介な解析の混乱: 曖昧さの明確化

C 11 では、ユニフォーム初期化子により、「最も厄介な解析」として知られる微妙な曖昧さが導入されます。この問題を示す例を詳しく見てみましょう:

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

class Timer {
public:
    Timer() {}
};

int main() {
    auto dv = Timer(); // What is Timer() ? And what type is dv?
    int time_keeper(Timer()); // This is a function right? And why isn't the argument " Timer (*) ()"?
    return 0;
}</code>

分析:

最初の行:

<code class="cpp">auto dv = Timer();</code>
  • Timer() とは何ですか? Timer() は、引数をとらない Timer クラスのコンストラクターです。 Timer 型のオブジェクトを初期化します。
  • dv の型は何ですか? dv は、初期化子からその型を推測する auto を使用して宣言されます。イニシャライザの型は Timer であるため、dv の型は Timer です。

2 行目:

<code class="cpp">int time_keeper(Timer());</code>
  • これは関数ですか? はい、これは関数宣言です。 int を返し、引数を取る time_keeper という関数を宣言しています。
  • 引数が "Timer () ()" ではないのはなぜですか? これは特殊なケースです。 「最も厄介な解析」の曖昧さ。関数が引数として別の関数に渡されると、その関数は自動的にその関数へのポインターに減衰します。したがって、この場合、引数は Timer () () ではなく、Timer() です。

これを証明するには、次のプログラムを考えてみましょう。

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

struct Timer { };
int main() {
    int time_keeper(Timer());
    static_assert(
        std::is_same<
            decltype(time_keeper),
            int(Timer(*)())
        >::value,
        "This should not fire!");
}</code>

このプログラムは正常にコンパイルされ、time_keeper が関数へのポインタを引数として受け取ることを確認します。

結論として、「最も厄介な解析」の混乱は、式 Timer() が次のように解釈できるという事実から生じています。 Timer 型のオブジェクト、または Timer を返す関数への関数ポインタのいずれか。正しい解釈は、その表現が使用されるコンテキストによって異なります。

以上が\"Timer()\" は関数ですか、それともオブジェクトですか? C の「最も厄介な解析」を理解する 11.の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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