none
A build problem of namespace std... RRS feed

  • 问题


  • #include <string>

    namespace google {
      namespace protobuf {
        using namespace std;  // Don't do this at home, kids.
        template <typename Element>
        class RepeatedPtrField {
        public:
          int size() const {
            return 1;
          }
        };
        string a;
      }  // namespace protobuf
    }  // namespace google

    class SMSG_Group_List {
    public:
      inline int member_size() const;
      ::google::protobuf::RepeatedPtrField< int > member_;
    };
    inline int SMSG_Group_List::member_size() const {
      return member_.size();
    }

    // My testing code below...
    class NewString{};
    typedef NewString string;

    template<typename t>
    void func() {
      string  a;  // I hope this string is NewString, CL said it's ambiguous...
      a.c_str();  // CL is good that it found this a NewString who has no c_str()...
    }

    void func2() {
      func<int>();
    }

    int main(int argc, char* argv[])
    {
     return 0;
    }

    Try compile the code above and there is a build error:

    bugproject.cpp(33) : error C2872: 'string' : ambiguous symbol

    bugproject.cpp(29) : NewString string'
    or       'k:\vs2008\vc\include\xstring(2210) : std::string'

    I am using VS2008 Version 9.0 and how can I fix this problem?...

    • 已移动 Andrew.Wu 2011年3月28日 3:14 (发件人:Visual Studio 相关讨论(Visual Studio 2010以前版本))
    2011年3月26日 12:52

答案

  • I think it is a defect in MS compiler. There has not a rule in C++ standard support this issue. And I compile it in Gcc. Only report the c_str() error.

    BRs


    麻烦把正确答案设为解答。
    • 已标记为答案 smallkhb 2011年3月30日 11:34
    2011年3月29日 8:12
    版主

全部回复

  • 你好,

    因为你的帖子是关于VC++的,我把这篇帖子移到了Visual C++论坛。在那边你可以得到更好的解答。

    谢谢你的理解与支持。


    Andrew Wu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年3月28日 3:14
  • try to use "std::string" because your current namespace could contains the symbol, and check your include "string.h" header file.
    2011年3月28日 3:32
  • Hi smallkhb,

    错误error C2872 表示編譯器無法判斷您參考至那一個符號。

    如果標頭檔包含 using Directive (C++),而後續標頭檔也用 #include 包含在內,其中包含也在 using 指示詞中所指定命名空間中的型別,可能會發生 C2872。請在所有標頭檔都以 #include 指定以後,再指定 using 指示詞。

    如需有關 C2872 的詳細資訊,請參閱 http://support.microsoft.com/default.aspx?scid=kb;en-us;316317

    下列範例會產生 C2872

    // C2872.cpp

    namespace A {

       int i;

    }

     

    using namespace A;

    int i;

    int main() {

       ::i++;   // ok

       A::i++;   // ok

          i++;   // C2872 ::i or A::i?

         }

       相关问题的帖子:

       http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f96176df-6ec4-40e0-a42b-e8d895a9faec

       http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/ad154421-c1d3-4188-8809-e47d03354504

       http://social.msdn.microsoft.com/forums/en-us/vclanguage/thread/DB9B6347-F6F1-474F-A6C6-0340A5C030A3

       如果您的问题解决了,请把有用的回答标记为答案!

       如果还有什么疑问请及时让我们知道,我们会尽量为您解决问题的。

     

       谢谢,

       Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年3月28日 10:37
    版主
  • HI,这个问题不知道你试过编译一下没,试试在那段代码的main函数中加入成为:

    。。。

    int main(int argc, char* argv[])
    {
      string a_new_str;

     a_new_str.c_str();
     return 0;
    }

    编译器对a_new_str的定义不会报错,并正确的认定它为NewString,同时报错说a_new_str没有c_str()的方法,因为a_new_str是一个NewString,这说明编译器并没有搞错,只要将这里的a_new_str.c_str()去掉,那string a_new_str就会通过编译,但那个模板里的那个string a却不幸的没有通过编译。

    事实上这个写在两层名字空间

    namespace google {

      namespace protobuf {

      // 作用域中的下面这句代码

      using namespace std;  // 并没有把std的名字空间暴露出来,它只在这个google::protobuf的作用域中存在,

     }

    }

    如果你在main中加入vector a_test_vector;//(当然记得#include <vector>)那么编译器会说这个vector没定义,因为std并没有被暴露出来;

    所以在main中使用string a_new_str;编译器会正确地将它解释为NewString;

    关键的问题在于当我使用了模板后,编译器的解释似乎出问题了,你看示例代码中的注释:

    template<typename t>
    void func() {
      string  a;  // I hope this string is NewString, CL said it's ambiguous...
      a.c_str();  // CL is good that it found this a NewString who has no c_str()...
    }

    编译报错的结果是:

    1:它认为string a是有二义的;

    2:但它又报错说c_str()不是NewString的成员,

    这里2的错误说明编译器知道那个a其实是个NewString,但它确又说string a是二义的,这很奇怪。

    再看这个代码:

        template <typename Element>
        class RepeatedPtrField {
        public:
          int size() const {
            return 1;
          }
        };
    当你在这个size()函数中加入这么一段成为:

        template <typename Element>
        class RepeatedPtrField {
        public:
          int size() const {

            string a_new_added_string;  // added for test
            return 1;
          }
        };

    这时编译器也会报和上面同样的错误,也就是说这个template的编译比想像中的要晚,因为它是在NewString被定义后才编译的,所以才会有二义。

    所以我觉得这个是名字空间和模板编译的问题,你觉得呢?...


    2011年3月28日 12:59
  • I think it is a defect in MS compiler. There has not a rule in C++ standard support this issue. And I compile it in Gcc. Only report the c_str() error.

    BRs


    麻烦把正确答案设为解答。
    • 已标记为答案 smallkhb 2011年3月30日 11:34
    2011年3月29日 8:12
    版主
  • Oh, no...

    I am now using the third party's code -- the google's protobuf to make proto code, and at the same time I am using a GameEngine code for develop. As using their header files together for build in VS2008, the problem occured. And it's not good for me to modify either's code because they are not writen by me, and they had a lot others codes relative to themself. Is there any suggestion to make this code pass the build?

    Many thanks...

    2011年3月30日 2:04
  • sure.

    One chocie, remove the using std namespace in google namespace, for instead using std::string in google.

    If you can not modify the code in google, you can change the typedef to another name. Or put your code in a namespace but not in global.


    麻烦把正确答案设为解答。
    2011年3月30日 6:35
    版主
  • Yes, thanks!

    2011年3月30日 11:34