別のテンプレート内でテンプレートを使用する場合は、次のように記述する必要があります。
vector<pair<int,int> > s;
空白なしで書くと、次のようになります。
vector<pair<int,int>> s;
エラーが発生します。
`>>' はネストされたテンプレート引数リスト内では `> >' でなければなりません
これは理解できると思いますが、どのような場合にこれが本当に曖昧になるのでしょうか?
別のテンプレート内でテンプレートを使用する場合は、次のように記述する必要があります。
vector<pair<int,int> > s;
空白なしで書くと、次のようになります。
vector<pair<int,int>> s;
エラーが発生します。
`>>' はネストされたテンプレート引数リスト内では `> >' でなければなりません
これは理解できると思いますが、どのような場合にこれが本当に曖昧になるのでしょうか?
したい場合もあります>>
。検討
boost::array<int, 1024>>2> x;
C++03 では、これは size の配列を正常に解析して作成します256
。
曖昧になることはありません。これは、C++0x ではテンプレートを閉じる間にスペースを書く必要がないという事実によって証明されています>
。
問題は、コンパイラが可能な限りコンテキストに依存しないように入力をトークン化することを好むということです。いずれにしても C++ は文脈に依存しない言語ではないため、この特殊なケースを 1 つ追加するだけで問題が特に難しくなるわけではありません。
現在の標準では、トークン化は貪欲であるため、として解析される>>
のと同じ方法で、単一のトークンとして処理されます。これが変更され、新しい標準になりました。コンパイラの実装者はより多くの作業を行う必要がありますが、全体としてはそれだけの価値があると見なされました (そして、いくつかの主要なコンパイラは、拡張機能として既にそれを実装しています)。a +++ b
a ++ + b
C++ は解析が非常に難しく、他のほとんどの言語よりもはるかに困難です。非常に一貫性のある言語ですが、入力のトークン化と構文の文法分析の理解の間で多くの作業が行われているため、コンパイラーにとって単純であるべきと思われることが、しばしばそうではありません。
歴史的な " >>
" 演算子は演算子です。ソースファイルがトークンに分割されているため、「識別」されます。これらのトークンは、後で文法分析中に何らかのコンテキストで「理解」されます (トークン化が完了してからかなり後)。
トークン化中に文法分析を行った場合は、「 >>
」がテンプレート宣言 (または定義) の 2 つのクロージャーと見なされるべきであるという区別を支援する「ヘルプ」があります。しかし、これは従来の C++ コンパイラの動作とは異なります。(新しいコンパイラは、文法分析とトークン化の間でより多くのフィードバックを行います。これには、これらのあいまいさを解決するための「先読み」が含まれます。)
はい、新しい C++0x 標準ではそれが変更され、コンパイラ ベンダーは実装を書き直して " >>
" を明確にする必要があります。したがって、今後も曖昧になることはありません。ただし、古い C++ コンパイラはこれを処理できないため、現時点では、' >
' 文字間のスペースと互換性のあるコードを維持することを「良い習慣」と見なすことができます。
適切な C++ 方言を設定して、このエラーを回避してください。たとえば、gcc 4.9 では、次のファイルは でコンパイルされませんg++
。
#include <vector>
#include <utility>
int main()
{
using namespace std;
vector<pair<int, int>> v; // compile error!
return 0;
}
物事の根底に行きましょう:
#include <iostream>
int main()
{
std::cout << __cplusplus << std::endl;
return 0;
}
このコードだけでコンパイルすると、g++ test.cpp
199711 が出力されます。gcc 4.9 は 2014 年にリリースされましたが、デフォルトの C++ 方言は GNU 拡張機能を備えた C++98 です。C++98 では、 と書く必要がありますvector<pair<int, int> >
。vector<pair<int, int>>
さらにコンパイルしたい場合は、-std=c++11
またはでコンパイルしてください-std=gnu++11
。
コンパイラに依存します。Visual Studio はこれを義務付けていません。つまり、g++ がエラーを生成している間は両方とも機能します。これはコンパイラの実装に依存すると思います。
C ++でクラスをプログラミングする際にこの問題が発生しましたが、次のようにして解決しました。
ここで前述したのと同じエラーを生成した行:
findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector<std::vector<cv::Point»&);
GCC Cross Compiler を通過して動作した行:
findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector< std::vector<cv::Point> >&);
私にとって、それは声明の解釈に関する単なる誤りでした。