当前位置:编程学习 > C/C++ >>

声明还是表达式?二义性?如何避免?

     通过一个实例来引出本文要阐述的问题。具体的代码为:
          deque<string> test;
         copy(istream_iterator<string> (cin), istream_iterator<string> (), back_inserter(test));
         上面的代码很明显是先声明了一个名为test的deque<string>容器,并将其初始化为空。然后,将从标准输入流(cin)中读入的以空格的一个个string推入容器,直到没有更多可用的输入为止。它等效于:
           deque<string> test;
           istream_iterator<string> first(cin) , last;
           copy(first, last, back_inserter(test));
           再看看使用下面的语句来声明一个同样的名为test的deque<string>容器。          
          deque<string> test(istream_iterator<string> (cin),istream_iterator<string> ());
           我们写出上面的语句的本意与之前的本意一样,从标准输入流(cin)中读入的以空格的一个个string推入容器,直到没有更多可用的输入为止。不过我们是想通过调用deque<string>的接受一对迭代器为参数的构造函数来实现其功能。那么它能完成我们设想的功能吗?
          其实”deque<string> test(istream_iterator<string> (cin),istream_iterator<string> ());“ 的功能只是声明一个名为test的函数,并且其返回值类型为deque<string>,而需要传入的参数有两个,第一个是类型为 istream_iterator<string>而名为cin的参数,第二个为不接受任何参数的无名参数。它并没有实现我们想要的“声明一个名为test的deque<string>对象,并通过传入的一对迭代器将其初始化”。为什么会出现这种情况呢?
           引用c++ 03标准的原话:当声明和表达式语句两者的语法形式之间可能出现二义性,即一个函数风格的显式类型转换作为其最左端的子表达式的表达式语句和一个其第一个声明子以“(”开头的声明语句可能会无法区分开。在这种情况下,该语句被解释为声明。
            简而言之就是当出现了声明与表达式二义性时,编译器总是会将其决议为声明。
            那么如何能够避免出现这种问题呢?
            既然这是由语法形式之间的二义性导致的,那么就可以将该语句“修饰”为非法的声明的语句从而消除其二义性。而想彻底的摆脱二义性,就不要使用那些会让有些编译器误认为时声明的语法形式。一般有两种方法:
            1.避免让编译器将其识别为一个函数声明,直接的做法就是:
              deque<string> test( (istream_iterator<string> (cin) ), ( istream_iterator<string> () ) );
             通过给参数添加额外的括号,提示编译器我们这里提供的是构造函数而非参数声明。冗余的括号使得这种形式的代码不可能被解释为合法的声明语句。
            2.使用具名变量作为构造函数的参数,彻底避免声明语句产生二义性。
             istream_iterator<string> first(cin) , last;
             deque<string> test(first , last);
           
            显然方法2的代码更佳清晰,而且更加便于维护。所以最好使用方法2来避免声明与语句的二义性。
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,