// This is a header file.
class MyClass; // It can be forward declared because the function uses reference.
// However, how can I do forward declaraion about std::wstring?
// class std::wstring; doesn't work.
VOID Boo(const MyClass& c);
VOID Foo(const std::wstring& s);
答案 0 :(得分:35)
你做不到。 #include <string>
,你几乎没有选择。
原因是wstring
在名称空间std
中定义,并且是std::basic_string<wchar_t>
的typedef。更详细地说,std::wstring
是std::basic_string<wchar_t, std::char_traits<wchar_t> >
。这意味着,为了向前声明std::wstring
,您必须在名称空间std::char_traits<>
内转发声明std::basic_string<>
和std
。因为(除少数例外)标准禁止向名称空间std
(17.4.3.1/1)添加定义或声明,最终您无法以符合标准的方式转发声明任何标准模板或类型。具体而言,这意味着您无法转发声明std::wstring
。
是的,我们都同意为<stringfwd>
设置<iosfwd>
标头会很方便,例如<iostream>
。但事实并非如此。 <string>
也不像<iostream>
那样编译核心,但仍然如此。您有两种选择:#include<string>
或使用opaque pointer。
答案 1 :(得分:3)
std::wstring
是一个模板实例化,所以你不能只是转发声明它。你必须使用头文件。
答案 2 :(得分:3)
我不认为避免#include&lt; string&gt;为您带来任何实际利益,但这就是您可以做到的:
namespace std {
template<class Char>
struct char_traits;
template<class T>
struct allocator;
template<class Char, class Traits, class Allocator>
struct basic_string;
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >
wstring;
}
// simple test that it's compatible:
std::wstring *p; // incomplete type at this point, but you can have a pointer
#include <string>
int main() {
std::wstring s = L"Hello, world!";
p = &s;
return 0;
}
你必须小心默认参数;特别是,这不起作用:
namespace std {
template<class Char>
struct char_traits;
template<class T>
struct allocator;
template<class Char, class Traits=char_traits<Char>,
class Allocator=allocator<Char> >
struct basic_string;
typedef basic_string<wchar_t> wstring;
}
#include <string>
使用include编译显示不兼容性:
In file included from /usr/include/c++/4.4/string:41,
from example.cpp:15:
/usr/include/c++/4.4/bits/stringfwd.h:52: error: redefinition of default argument for ‘class _Traits’
example.cpp:8: note: original definition appeared here
答案 3 :(得分:2)
您无法在符合要求的实施中转发声明std::wstring
,而不是因为typedef
专业化是template
,或者它有可能是未知数量的std
模板参数(它没有;严格指定这些参数),但因为对符合程序的约束禁止它们向std::wstring
命名空间添加任何声明或定义,而不是专门用于标准模板的显式特化用户定义的类型。
此约束在17.4.3.1 [lib.reserved.names] / 1中说明。#include <string>
的前向声明没有例外,您必须std::wstring
进行声明{{1}以合规的方式提供。
答案 4 :(得分:-2)
class std::wstring;
无法编译。但这样做:
namespace std{
class wstring;
}
但是,此声明不兼容与<string>
标头文件,如果您#include <string>
之后,您应该看到该文件。所以这真的不安全。