std::wstring 的前向声明

发布于 2024-10-13 22:47:00 字数 303 浏览 5 评论 0 原文

// 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);
// 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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

骄傲 2024-10-20 22:47:00

std::wstring 是一个模板实例化,因此您不能只转发声明它。您必须使用头文件。

std::wstring is a template instantiation, so you can't just forward declare it. You'll have to use the header file.

瞳孔里扚悲伤 2024-10-20 22:47:00

您不能在一致的实现中转发声明 std::wstring ,不是因为它是 template 专门化的 typedef 或者有它有可能具有未知数量的模板参数(事实并非如此;这些是严格指定的),但因为对符合程序的约束禁止它们向 std 添加任何声明或定义除了专用于用户定义类型的标准模板的显式专用化之外的命名空间。

此约束在 17.4.3.1 [lib.reserved.names] / 1 中进行了说明。std::wstring 的前向声明也不例外,必须#include < /code> 使声明 std::wstring 以一致的方式可用。

You can't forward declare std::wstring in a conforming implementation, not because it is a typedef for a template specialization or that there is any possibility that it has an unknown number of template arguments (it doesn't; these are strictly specified) but because there is a constraint on conforming programs that prohibits them from adding any declarations or definitions to the std namespace other than explicit specializations of standard templates which are specialized on a user-defined type.

This constraint is stated in 17.4.3.1 [lib.reserved.names] / 1. There is no exception for forward declarations of std::wstring, you must #include <string> to make a declaration std::wstring available in a conforming way.

长亭外,古道边 2024-10-20 22:47:00

class std::wstring; 无法编译。但事实确实如此:

namespace std{
class wstring;
}

但是,此声明与 头文件不兼容,如果您#include ,您应该会看到该头文件。代码> 之后。所以确实不安全。

class std::wstring; doesn't compile. But this does:

namespace std{
class wstring;
}

However, this declaration is incompatible with the <string> header file, which you should see if you #include <string> after it. So it's really not safe.

与之呼应 2024-10-20 22:47:00

我不认为避免 #include 会给你带来任何真正的好处,但这就是你可以做到的:

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

I don't think avoiding #include <string> gains you any real benefit, but this is how you could do it:

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;
}

You have to be careful of default parameters; in particular, this would not work:

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>

Compiled with the include shows the incompatibility:

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
生生漫 2024-10-20 22:47:00

你不能。 #include ,你(几乎)别无选择。

原因是 wstring 是在命名空间 std 中定义的,并且类型定义为 std::basic_string。更详细地说,std::wstring 是 std::basic_string 。 >。这意味着为了转发声明 std::wstring 你必须转发声明 std::char_traits<>std::basic_string< ;> 命名空间 std 内。因为(除了少数例外)标准禁止向命名空间 std (17.4.3.1/1) 添加定义或声明,最终您无法在符合标准的情况下前向声明任何标准模板或类型方式。具体来说,这意味着您无法前向声明 std::wstring

是的,我们都同意拥有 标头会很方便,例如 。但没有。 也不像 那样编译困难,但尽管如此。您有两种选择:#include 或使用不透明指针< /a>.

You can't. #include <string>, you have (almost) no choice.

The reason is that wstring is defined in namespace std and is typedef'd to std::basic_string<wchar_t>. More elaborately, std::wstring is std::basic_string<wchar_t, std::char_traits<wchar_t> >. This means that in order to forward-declare std::wstring you'd have to forward-declare std::char_traits<> and std::basic_string<> inside namespace std. Because (apart from a few exceptions) the standard forbids adding definitions or declarations to namespace std (17.4.3.1/1) ultimately you can't forward-declare any standard template or type in a standard-conforming way. Specifically, this means you can't forward-declare std::wstring.

And yes, we all agree it would be convenient to have a <stringfwd> header, like <iosfwd> for <iostream>. But there isn't. <string> is also not nearly as hardcore to compile as <iostream>, but nevertheless. You have two choices: #include<string> or use an opaque pointer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文