提问人:Michael J 提问时间:6/18/2012 最后编辑:Michael J 更新时间:6/23/2012 访问量:2033
std::basic_stringstream<unsigned char> 不会使用 MSVC 10 进行编译
std::basic_stringstream<unsigned char> won't compile with MSVC 10
问:
我正在尝试让 UTF-8 字符与 ANSI 8 位字符共存。我的策略是表示 utf-8 字符,以便可以对这两种字符类型使用适当的函数重载。unsigned char
例如
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 日 **
好吧,我已经更接近理解这一点,但不是如何解决它。
众所周知,静态类变量被定义了两次:
- 一旦进入类定义和
- 一旦超出建立存储空间的类定义。
例如
// 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;
// ...
}
当标头包含在应用程序中时,定义为 ,这意味着变量是从 dll 导入的。_CRTIMP2_PURE
__declspec(dllimport)
现在,标头还包含以下内容
template<class _Elem>
locale::id numpunct<_Elem>::id;
请注意缺少限定符。__declspec(dllimport)
即类声明说变量的静态链接在 dll 中,但对于一般情况,它在 dll 之外声明。id
对于已知的病例,有专业化。
template locale::id numpunct<char>::id;
template locale::id numpunct<wchar_t>::id;
它们受 s 保护,因此仅在生成 DLL 时才包含它们。否则,它们将被排除在外。#if
即 numpunct 的 char
和 wchar_t
版本在 dll 中
因此,我们有类定义说 id 的存储位于 DLL 中,但这仅适用于 和 specialisations,这意味着我的无符号 char 版本注定要失败。:-(char
wchar_t
我能想到的唯一方法是创建我自己的专业化:基本上从头文件中复制它并修复它。这引发了许多问题。
有人有更好的主意吗?
答: 暂无答案
评论
ostr << uchar('a');
ostr << "Something";