模板中的模板:为什么“>>”应该是“>” >'在嵌套模板参数列表中”

发布于 2024-11-19 23:08:05 字数 326 浏览 5 评论 0 原文

我知道当我们在另一个模板中使用模板时,我们应该这样写:

vector; > s;

如果我们不带空格地编写它:

vector> s;

我们会得到一个错误:

`>>'应该是“>” >'在嵌套模板参数列表中

我认为这是可以理解的,但我只是忍不住想知道,在什么情况下这真的会很不明确?

I know that when we are using template inside another template, we should write it like this:

vector<pair<int,int> > s;

and if we write it without the whitespace:

vector<pair<int,int>> s;

we will get an error:

`>>' should be `> >' within a nested template argument list

I see this is understandable, but I just can't help but wondering, in which cases will this be really ambiguous?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

无悔心 2024-11-26 23:08:06

有时您希望它是>>。考虑

boost::array<int, 1024>>2> x;

在 C++03 中,这成功地解析并创建了一个大小为 256 的数组。

Sometimes you want it to be >>. Consider

boost::array<int, 1024>>2> x;

In C++03 this successfully parses and creates an array of size 256.

生寂 2024-11-26 23:08:06

永远不会有歧义。事实证明了这一点,在 C++0x 中,您不必再在关闭模板 > 之间编写空格。

问题是编译器更愿意尽可能独立于上下文对输入进行标记。由于 C++ 无论如何都不是一种上下文无关的语言,因此仅添加这个特殊情况并不会让事情变得特别困难。

It won't ever be ambiguous. This is proven by the fact that in C++0x you don't have to write a space between closing template >s any more.

The thing is that the compilers would prefer to tokenize the input as context-independently as possible. Since C++ is not a context independent language anyway, adding just this one special case isn't going to make things particularly harder.

送舟行 2024-11-26 23:08:06

在当前标准(C++03)中,标记化是贪婪的,因此 >> 将被作为单个标记进行处理,与 a +++ ba +++ b 相同。 code> 将被解析为 a ++ + b。这在新标准 (C++11) 中发生了变化。虽然它需要编译器实现者做更多的工作,但人们认为总体而言这是值得的(而且一些主要编译器已经将其实现为扩展)。

In the current standard (C++03), tokenization is greedy, so >> will be processed as a single token, in the same way that a +++ b will be parsed as a ++ + b. This has changed in the new standard (C++11). While it requires more work from the compiler implementors, it was deemed that overall it is worth it (and some major compilers already implement that as an extension anyway).

孤独患者 2024-11-26 23:08:06

C++ 确实非常难以解析——比大多数其他语言都困难得多。它是一种非常一致的语言,但是在对输入进行标记和理解语法的语法分析之间做了很多工作,以至于对于编译器来说看起来应该很简单的事情通常并非如此。

历史上的“>>”运算符是一个运算符。当源文件被分解为标记时,它被“识别”。然后,这些标记在语法分析期间(在标记化完成后很久)在某些上下文中被“理解”。

如果您在标记化时进行了语法分析,那么您可以“帮助”来帮助区分“>>”应该被视为模板的两个闭包声明(或定义)。然而,这并不是历史上 C++ 编译器的工作方式。 (新编译器在语法分析和标记化之间进行更多反馈,包括更多“前瞻”以帮助解决这些歧义。)

是的,新的 C++0x 标准改变了这一点,并迫使编译器供应商重新编写其实现以消除歧义在你的情况下为“>>”。所以,今后的发展,绝不会含糊。但是,较旧的 C++ 编译器无法处理该问题,因此目前保持代码与 '>' 字符之间的空格兼容可能被认为是“良好实践”。

C++ is really incredibly hard to parse -- much more difficult than most other languages. It is a very consistent language, but so much work is done between tokenizing the input and understanding the grammatical analysis of the syntax, that things that seem like they should be simple for a compiler, often are NOT.

The historical ">>" operator is an operator. It is "identified" as the source file is broken into tokens. Those tokens are then later "understood" in some context during grammatical analysis (long after tokenization is complete).

If you did grammatical analysis while you tokenized, then you have "helps" to assist in the distinction that ">>" should be considered as two closures to a template declaration (or definition). Yet, this is historically not how historical C++ compilers work. (New compilers do more feedback between grammatical analysis and tokenization, including more "look-aheads" to help resolve these ambiguities.)

Yes, the new C++0x standard changes that, and forces compiler vendors to re-write their implementations to disambiguate ">>" in your case. So, it will never be ambiguous going forward. However, older C++ compilers cannot handle that, so it may be considered "good practice" to keep your code compatible with the space between the '>' characters for now.

空城缀染半城烟沙 2024-11-26 23:08:06

通过设置适当的 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 >。如果您更喜欢 vector> ,请使用 -std=c++11-std=gnu++11 进行编译代码>.

Avoid this error by setting an appropriate C++ dialect. For example, with gcc 4.9 the following file does not compile with g++:

#include <vector>
#include <utility>

int main()
{
    using namespace std;
    vector<pair<int, int>> v; // compile error!
    return 0;
}

Let's get to the bottom of things:

#include <iostream>

int main()
{
    std::cout << __cplusplus << std::endl;
    return 0;
}

Compiled with just g++ test.cpp this code prints 199711. Although gcc 4.9 was released in 2014 the default C++ dialect is C++98 with GNU extensions. C++98 requires us to write vector<pair<int, int> >. If you like vector<pair<int, int>> more compile with -std=c++11 or -std=gnu++11.

腻橙味 2024-11-26 23:08:06

这取决于编译器。 Visual Studio 不强制要求这样做,即两者都可以工作,而 g++ 会产生错误。我认为这取决于编译器的实现。

It depends on the compiler. Visual Studio does not mandate this i.e. both works while g++ produces an error. I think that this depends on the compiler implementation.

过气美图社 2024-11-26 23:08:06

我在用 C++ 编写一个类时遇到了这个问题,我通过执行以下操作解决了这个问题:

产生之前提到的相同错误的行:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector<std::vector<cv::Point»&);

通过 GCC 交叉编译器并工作的行:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector< std::vector<cv::Point> >&);

对我来说,这只是解释上的错误声明。

I had this issue programing a class in c++, and i solved it by doing the following:

Line that produced the same error mentioned here before:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector<std::vector<cv::Point»&);

Line that passed through GCC Cross Compiler and Worked:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector< std::vector<cv::Point> >&);

For me it was just an error on the interpretation of the statement.

懒的傷心 2024-11-26 23:08:06

流语法

cin >> var;

VS

嵌套模板语法

For>

编译器第一阶段,词法分析器将无法识别。

Stream Syntax

cin >> var;

Vs

Nested Template Syntax

For<Bar<Barz>>

First phase of Compiler, lexical analyser will not be able to recognise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文