8

友人と私は 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)テンプレート引数ですか、それともテンプレート引数ですか?

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

4

4 に答える 4

7

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

new A<(b > c)>(d);
于 2008-09-09T18:57:00.283 に答える
6

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"
于 2008-09-16T12:27:15.793 に答える
3

C++ 標準では、テンプレート名の後に が続く場合<<が常にテンプレート引数リストの先頭であり、ネストされていない最初の引数が>テンプレート引数リストの末尾と見なされると定義されています。

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

于 2008-09-09T20:50:28.793 に答える
0

lexer の貪欲さは、括弧を明示的に使用しないことの決定的な要因である可能性があります。レクサーは貪欲ではないと思います。

于 2008-09-09T18:18:18.630 に答える