C++ C++;0x、编译器挂钩和硬编码语言功能

C++ C++;0x、编译器挂钩和硬编码语言功能,c++,c++11,compiler-construction,initializer-list,C++,C++11,Compiler Construction,Initializer List,我对C++0x的一些新特性有点好奇。特别是和。这两个功能都需要用户定义的类才能正常工作 我突然来了,虽然上面的答案很有帮助。我不知道它是否完全正确(我可能只是完全误解了,见第一个答案的第三条评论)。根据for初始值设定项列表,标头定义了一种类型: template<class E> class initializer_list { public: initializer_list(); size_t size() const; // number of elemen

我对C++0x的一些新特性有点好奇。特别是和。这两个功能都需要用户定义的类才能正常工作

我突然来了,虽然上面的答案很有帮助。我不知道它是否完全正确(我可能只是完全误解了,见第一个答案的第三条评论)。根据for初始值设定项列表,标头定义了一种类型:

template<class E> class initializer_list {
public:
    initializer_list();

    size_t size() const; // number of elements
    const E* begin() const; // first element
    const E* end() const; // one past the last element
};
模板类初始值设定项\u列表{
公众:
初始值设定项_list();
size\u t size()const;//元素数
常量E*begin()常量;//第一个元素
const E*end()const;//最后一个元素后面的一个
};
您可以在规范中看到这一点,只需Ctrl+F“类初始值设定项列表”

为了将
={1,2,3}
隐式转换到
初始值设定项列表
类中,编译器必须了解
{}
初始值设定项列表
之间的关系。没有任何构造函数接收任何内容,因此据我所知,初始值设定项列表是一个包装器,它绑定到编译器实际生成的任何内容

这与(:)循环的
相同,它也需要用户定义的类型才能工作(尽管根据规范,更新后的数组和初始值设定项列表不需要任何代码。但是初始值设定项列表需要
,所以它是代理的用户定义代码要求)

我完全误解了这是怎么回事吗?我认为这些新特性实际上非常依赖于用户代码,这并没有错。感觉这些特性是半生不熟的,而不是将整个特性构建到编译器中,而是一半由编译器完成,一半在includes中完成。这是什么原因


编辑:我键入了“严重依赖编译器代码”,而不是“严重依赖用户代码”。我想这完全抛开了我的问题。我的困惑不在于编译器中内置的新功能,而在于编译器中内置的依赖于用户代码的东西。

这只是语法糖。编译器将将给定的语法结构扩展为直接引用标准类型/符号名称的等效C++表达式。 <>这不是现代C++编译器在语言和“外部世界”之间唯一的强耦合。例如,
extern“C”
是一种适应C的链接模型的语言黑客。声明线程本地存储的面向语言的方法隐式地依赖于大量RTL黑客的工作

或者看看C。如何访问通过
传递的参数?您需要依赖标准库;但这使用了一种魔术,它对C编译器如何精确地布局堆栈帧有着非常严格的依赖性

更新:

如果有什么,方法C++在这里比C++的更为重要——它将添加一个内在的集合或范围类型,并被嵌入到语言中。相反,它是通过供应商定义的范围类型来完成的。我真的看不出它与可变参数有多大不同,如果没有供应商定义的访问器宏,可变参数同样是无用的

我认为这些新特性实际上非常依赖于编译器代码,这并没有错

他们确实非常依赖编译器。无论是否需要包含头,事实上,在这两种情况下,今天的编译器都会出现语法分析错误。(:)
不太适合今天的标准,其中唯一允许的构造是(;;)

感觉这些特性是半生不熟的,而不是将整个特性构建到编译器中,而是一半由编译器完成,一半在includes中完成。这是什么原因

支持必须在编译器中实现,但需要包含系统头才能工作。这有两个目的,在初始化列表的情况下,它将类型(编译器支持的接口)带入用户的范围,这样您就可以使用它(想想C中的va_参数是如何使用的)。对于基于范围的for(这只是语法上的糖分),您需要将范围引入范围,以便编译器能够执行它的魔力。请注意,本标准将(范围声明:表达式)语句的
定义为等同于([6.5.4]/1在草案中):

{
自动范围=(表达式);
对于(自动开始=标准::范围::开始(uuu范围),
__结束=标准::范围::结束(_范围);
__开始!=\u结束;
++__开始{
对于范围声明=*\u开始;
陈述
} 
} 
如果您只想在数组和STL容器上使用它,而这些数组和STL容器可以在没有
范围
概念的情况下实现(不是在C++0x意义上),但是如果您想将语法扩展到用户定义的类(您自己的容器),编译器可以很容易地依赖现有的
范围
模板依赖定义的模板的机制相当于需要容器上的静态接口

大多数其他语言都朝着需要常规接口的方向发展(比如说容器,…)使用运行时多态性,如果要在C++中完成,整个STL必须经过一个主要的重构,因为STL容器不共享一个共同的基础或接口,而且它们也不准备被使用。 如果有的话,当前的标准在发布时不会被低估。

…和extern“C”是语言特性,但是,您不需要将扩展的类写入参数,您只需要使用…来指示编译器应该做什么。{}另一方面,需要名为initializer\u list的类,如果不存在,它将不存在
{ 
   auto && __range = ( expression ); 
   for ( auto __begin = std::Range<_RangeT>::begin(__range), 
         __end = std::Range<_RangeT>::end(__range); 
         __begin != __end; 
         ++__begin ) { 
      for-range-declaration = *__begin; 
      statement 
   } 
}