質問

友人と私は C++ テンプレートについて話し合っていました。彼は私に、これは何をすべきかを尋ねました。

#include <iostream>

template <bool>
struct A {
    A(bool) { std::cout << "bool\n"; }
    A(void*) { std::cout << "void*\n"; }
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new A< b > (c) > (d);
}

main の最後の行には 2 つの適切な解析が含まれています。'b' はテンプレート引数ですか、それとも b > (c) テンプレート引数?

これをコンパイルして何が得られるかを確認するのは簡単ですが、何がこの曖昧さを解決するのか疑問に思いました。

役に立ちましたか?

解決

私の知る限り、それは次のようにコンパイルされます new A<b>(c) > d. 。これは私見ですが、それを解析する唯一の合理的な方法です。パーサーが通常の状況で > テンプレート引数の終了を想定できない場合、さらにあいまいさが生じます。逆にしたい場合は、次のように書く必要があります。

new A<(b > c)>(d);

他のヒント

Leon と Lee が述べているように、14.2/3 (C++ '03) ではこの動作を明示的に定義しています。

C++ '0x では、同様のルールが適用されてさらに楽しくなります。 >>. 。基本的な概念は、テンプレート引数リストを解析するときに、ネストされていない引数リストを解析するということです。 >> 2 つの異なるものとして扱われます > > 右シフト演算子ではなくトークン:

template <bool>
struct A {
  A(bool);
  A(void*);
};

template <typename T>
class C
{
public:
  C (int);
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new C <A< b  >>  (c) > (d); // #1
    new C <A< b > >  (c) > (d); // #2
}

上記の「#1」と「#2」は同等です。

もちろん、これにより、ネストされた特殊化にスペースを追加する必要がある煩わしさは修正されます。

C<A<false>> c;  // Parse error in C++ '98, '03 due to "right shift operator"

C++ 標準では、テンプレート名の後に <, 、 < は常にテンプレート引数リストの先頭であり、ネストされていない最初の引数です。 > は、テンプレート引数リストの最後とみなされます。

の結果を意図した場合は、 > 演算子がテンプレート引数である場合は、式を括弧で囲む必要があります。引数が引数の一部である場合は括弧は必要ありません。 static_cast<> または別のテンプレート式。

おそらく、レクサーの貪欲さが、それを明示するための括弧の欠如の決定要因です。レクサーは貪欲ではないと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top