std :: basic_stringstream <unsigned char =“”>将无法使用MSVC 10 </unsigned>进行编译

时间:2012-06-18 02:08:21

标签: c++ visual-c++ unicode utf-8 stringstream

我试图让UTF-8字符与ANSI 8位字符共存。我的策略是将utf-8字符表示为unsigned char,以便可以对两种字符类型使用适当的函数重载。

e.g。

    namespace MyStuff
    {
        typedef uchar utf8_t;
        typedef std::basic_string<utf8_t> U8string;
    }
    void SomeFunc(std::string &s);
    void SomeFunc(std::wstring &s);
    void SomeFunc(MyStuff::U8string &s);

这一切都很有效,直到我尝试使用字符串流。

    std::basic_ostringstream<MyStuff::utf8_t> ostr;
    ostr << 1;

MSVC Visual C ++ Express V10无法编译:

c:\program files\microsoft visual studio 10.0\vc\include\xlocmon(213): 
    warning C4273: 'id' : inconsistent dll linkage
    c:\program files\microsoft visual studio 10.0\vc\include\xlocnum(65) : 
            see previous definition of 
            'public: static std::locale::id std::numpunct<unsigned char>::id'
    c:\program files\microsoft visual studio 10.0\vc\include\xlocnum(65) : 
            while compiling class template static data member 'std::locale::id 
            std::numpunct<_Elem>::id'
    with
    [
        _Elem=Tk::utf8_t
    ]
    c:\program files\microsoft visual studio 10.0\vc\include\xlocnum(1149) : 
        see reference to function template instantiation 
        'const _Facet &std::use_facet<std::numpunct<_Elem>>(const std::locale &)' 
        being compiled
    with
    [
        _Facet=std::numpunct<Tk::utf8_t>,
        _Elem=Tk::utf8_t
    ]
    c:\program files\microsoft visual studio 10.0\vc\include\xlocnum(1143) : 
        while compiling class template member function 
        'std::ostreambuf_iterator<_Elem,_Traits> 
        std::num_put<_Elem,_OutIt>::
        do_put(_OutIt,std::ios_base &,_Elem,std::_Bool) const'
    with
    [
        _Elem=Tk::utf8_t,
        _Traits=std::char_traits<Tk::utf8_t>,
        _OutIt=std::ostreambuf_iterator<Tk::utf8_t,std::char_traits<Tk::utf8_t>>
    ]
    c:\program files\microsoft visual studio 10.0\vc\include\ostream(295) : 
        see reference to class template instantiation 'std::num_put<_Elem,_OutIt>' 
        being compiled
    with
    [
        _Elem=Tk::utf8_t,
        _OutIt=std::ostreambuf_iterator<Tk::utf8_t,std::char_traits<Tk::utf8_t>>
    ]
    c:\program files\microsoft visual studio 10.0\vc\include\ostream(281) : 
        while compiling class template member function 
        'std::basic_ostream<_Elem,_Traits> &
        std::basic_ostream<_Elem,_Traits>::operator <<(int)'
    with
    [
        _Elem=Tk::utf8_t,
        _Traits=std::char_traits<Tk::utf8_t>
    ]
    c:\program files\microsoft visual studio 10.0\vc\include\sstream(526) : 
        see reference to class template instantiation 
        'std::basic_ostream<_Elem,_Traits>' being compiled
    with
    [
        _Elem=Tk::utf8_t,
        _Traits=std::char_traits<Tk::utf8_t>
    ]
    c:\users\michael\dvl\tmp\console\console.cpp(23) : 
        see reference to class template instantiation 
        'std::basic_ostringstream<_Elem,_Traits,_Alloc>' being compiled
    with
    [
        _Elem=Tk::utf8_t,
        _Traits=std::char_traits<Tk::utf8_t>,
        _Alloc=std::allocator<uchar>
    ]

c:\program files\microsoft visual studio 10.0\vc\include\xlocmon(213): 
    error C2491: 'std::numpunct<_Elem>::id' : definition of dllimport 
    static data member not allowed
    with
    [
        _Elem=Tk::utf8_t
    ]

有什么想法吗?

** 2012年6月19日编辑**

好的,我已经接近理解这个,但不是如何解决它。

众所周知,静态类变量定义了两次:

  • 一次在课程定义中
  • 一旦超出了建立存储空间的类定义。

e.g。

    // in .h file
    class CFoo
    {
        // ...
        static int x;
    };

    // in .cpp file
    int CFoo::x = 42;

现在在VC10标题中我们得到这样的结果:

    template<class _Elem>
    class numpunct : public locale::facet
    {
        // ...
        _CRTIMP2_PURE static locale::id id;
        // ...
    }

当标头包含在应用程序中时,_CRTIMP2_PURE被定义为__declspec(dllimport),这意味着该变量是从dll导入的。

现在标题还包含以下内容

    template<class _Elem>
    locale::id numpunct<_Elem>::id;

请注意缺少__declspec(dllimport)限定符。

即。类声明说明id变量的静态链接在dll中,但对于一般情况,它在dll之外声明。

对于已知案例,有专业化。

    template locale::id numpunct<char>::id;
    template locale::id numpunct<wchar_t>::id;

这些受#if保护,因此只有在构建DLL时才包含它们。否则他们被排除在外。

即。 dll中的charwchar_t版本的numpunct

所以我们有类定义说id的存储在DLL中,但这仅适用于charwchar_t特化,这意味着我的unsigned char版本注定失败。 : - (

我能想到的唯一前进方法是创建自己的专业化:基本上从头文件中复制并修复它。这引发了许多问题。

有人有更好的主意吗?

0 个答案:

没有答案