Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在模板求值的第一阶段确定名称的类型,即使是依赖名称?_C++_Templates - Fatal编程技术网

C++ 为什么在模板求值的第一阶段确定名称的类型,即使是依赖名称?

C++ 为什么在模板求值的第一阶段确定名称的类型,即使是依赖名称?,c++,templates,C++,Templates,作为a的推论,我很好奇为什么模板中的名称类型(“该名称的类别”)是在2阶段查找的第一阶段设置的,而类别本身也可以依赖于模板参数。这种行为的真正好处是什么 一点澄清-我想我对2阶段查找的工作原理有一个合理的理解;我试图理解的是,为什么令牌的类别在阶段1中确定,这与确定依赖类型(在阶段2)时不同。我的论点是,简化困难的语法,使代码更易于编写和阅读,这是一个非常实际的好处,因此我很好奇,将类别计算限制在阶段1的令人信服的原因是什么。这仅仅是为了在模板实例化之前获得更好的模板验证/错误消息,还是为了略微

作为a的推论,我很好奇为什么模板中的名称类型(“该名称的类别”)是在2阶段查找的第一阶段设置的,而类别本身也可以依赖于模板参数。这种行为的真正好处是什么


一点澄清-我想我对2阶段查找的工作原理有一个合理的理解;我试图理解的是,为什么令牌的类别在阶段1中确定,这与确定依赖类型(在阶段2)时不同。我的论点是,简化困难的语法,使代码更易于编写和阅读,这是一个非常实际的好处,因此我很好奇,将类别计算限制在阶段1的令人信服的原因是什么。这仅仅是为了在模板实例化之前获得更好的模板验证/错误消息,还是为了略微提高速度?或者模板是否有一些基本属性使得第2阶段类别评估变得不可行?

问题可能有两个:为什么我们首先需要两阶段查找,并且既然我们有两阶段查找,为什么在第一阶段对标记的解释是固定的。第一个问题很难回答,因为这是语言中的一个设计决策,因此它有它的优点和缺点,取决于你的立场,一个或另一个将具有更大的权重

第二部分,也就是你感兴趣的部分,实际上要简单得多。为什么,在C++语言中,具有两阶段查找的令牌含义在第一阶段固定,不能在第二阶段被解释。原因是C++具有语境语法,而符号的解释高度依赖语境。如果不在第一阶段确定标记的含义,您甚至不知道首先需要查找哪些名称

考虑对原始代码稍作修改的版本,其中文字5由常量表达式替换,并假设您不需要提供上次插入的
模板
类型名
关键字:

const int b = 5;
template<typename T>
struct Derived : public Base<T> {
    void Foo() { 
       Base<T>::Bar<false>(b);   // [1]
       std::cout << b;           // [2]
    }
};
const int b=5;
模板
结构派生:公共基{
void Foo(){
基::条(b);//[1]

C++:C++的很多优点是它是严格检查的语言。你尽可能清楚地表达程序的意图,编译器告诉你这个意图是否被违反了。 我无法想象你会写出
Base::Bar(b);
(来自Dribeas的例子)而没有你想要的特定解释,如果某人提供的类型具有
静态
成员
条形
或嵌套模板类型而不是成员函数模板,则可能会生成有意义的错误


其他语言在设计上强调简洁而不是静态分析;例如,许多动态语言都有大量的“照我说的做”规则。当编译器将不合理的代码变成不可预测的、没有错误的代码时,这会带来乐趣。(举个例子:Perl。我喜欢文本操作,但DWIM很烦人。几乎所有的东西都是运行时错误,几乎没有任何静态检查可言)

名称类型的类型在第一阶段没有设置。唯一知道的是它指的是类型而不是非类型。实际类型直到实例化才知道。@JesseGood:将问题中的类型解释为类别,即它是否指类型、模板或两者都不指。您主要关心的是什么,广告是什么两阶段查找的优势,或者为什么在两阶段查找的上下文中,每个令牌的类别必须在第一次通过时固定?我已经尝试了几次提供答案,但结果变得太广泛,我仍然觉得我可能没有解决真正的问题。后一个问题-为什么必须确定类别(这是这个问题的恰当术语吗?)在第1阶段确定每个名称的名称。参考问题证明,在第2阶段确定该类别具有明显的优势,因此对我来说,允许在第2阶段确定类别是有意义的,因为可能存在多个类别。这个答案的大部分似乎本质上是“因为它是两阶段查找,所以令牌类别在第一阶段确定",但尽管这些示例说明了这个问题,但它们并没有提供一个很好的答案。我仍然不能说我知道确保在第一阶段定义标记类别的好处是什么;为什么不允许在第二阶段评估不明确的类别,就像不明确的类型那样?即使我们在您的示例中指定Bar是临时的后期类型,编译器仍然无法确定
cout@Rollie的有效性:这正是为什么我问您是否对两阶段查找优于一阶段查找感兴趣,或者给定两阶段查找是否需要在第一阶段对符号进行分类。示例很有说明性:一行代码e和三个不同的选项。如果在请求不同的选项进行查找时存储,则最终会得到一组成倍增长的可选分区,这些分区需要与每一个分区的查找结果一起维护。只在第二阶段放弃除一个以外的所有选项。[…][…]你意识到这个替代方案没有意义吗?它基本上意味着:在第一阶段,你做了大量的工作,并跟踪多个替代方案。然后在第二阶段,你做同样的工作,基本上忽略了结果(代价高昂)第一阶段。如果您想用这种语言提供解决方案,那么解决方案很简单:避免两阶段查找,只执行第二阶段,即