C++0x,带有友元运算符“”()的用户定义文字

发布于 2024-12-03 11:17:36 字数 386 浏览 4 评论 0原文

运算符“”(...)定义为友元函数是否可能和/或有用?

class Puzzle {
  friend Puzzle operator "" _puzzle(const char*, size_t);
  ...
};
void solve(Puzzle);
int main() {
  solve("oxo,xox"_puzzle);
};

我特别考虑“有用”,因为规则规定operator "" 只能在命名空间中定义——尤其是因为以_ 开头的标识符在全局命名空间中保留。这位朋友在这里违反了这条规则吗?那么,这种不完全封装不会有任何好处,对吗?

Will it be possible and/or useful to define an operator "" (...) as a friend function?

class Puzzle {
  friend Puzzle operator "" _puzzle(const char*, size_t);
  ...
};
void solve(Puzzle);
int main() {
  solve("oxo,xox"_puzzle);
};

I am thinking about "useful" especially, because of the rule that operator "" shall be defined in a namespace only -- not the least because identifiers beginning with _ are reserved in global namespace. Is this friend breaking this rule here? So, there would be no benefit with this not-quite encapsulation, right?

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

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

发布评论

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

评论(3

时光与爱终年不遇 2024-12-10 11:17:36

该标准在唯一提到对用户定义文字声明的任何限制的地方直接解决了这个问题,第 13.5.8/2 节:

其 declarator-id 为文字运算符 id 的声明应为名称空间范围函数或函数模板的声明(它可以是友元函数 (11.3))、显式函数模板的实例化或专门化,或 using 声明 (7.3.3)。

如果友元也在命名空间范围内声明,则类或命名空间范围中的定义之间没有区别。请注意,不需要在命名空间范围内进行定义,您的问题目前的措辞是断言的。

如果未在名称空间范围内声明,则由于 ADL 无法找到它,因此友元可以通过常规非限定名称查找在其范围内的类中私有使用。这是声明非外部接口的文字运算符的唯一方法。

如果友元是在类模板内定义的,则模板的两个实例化将在命名空间范围内生成两个同名的函数,即使它们在类范围之外都是不可见的,但它们会发生冲突。

The Standard addresses this directly in the only place it mentions any restrictions on the declarations of user-defined literals, §13.5.8/2:

A declaration whose declarator-id is a literal-operator-id shall be a declaration of a namespace-scope function or function template (it could be a friend function (11.3)), an explicit instantiation or specialization of a function template, or a using-declaration (7.3.3).

If the friend is also declared at namespace scope, then there is no distinction between definition in class or namespace scope. Note that there is no requirement for definition at namespace scope, which your question as currently worded asserts.

If not declared at namespace scope, since it cannot be found by ADL, the friend could be used privately inside the class where it is scope by regular unqualified name lookup. This is the only way of declaring a literal operator which is not an external interface.

If the friend is defined inside a class template, then two instantiations of the template will generate two identically-named functions at namespace scope, which collide even though they are both invisible outside the class scope.

许你一世情深 2024-12-10 11:17:36

如果它对语法有帮助,下面是我在类中声明朋友用户定义的文字运算符的方法,其中运算符本身位于命名空间中:

class Integer;
namespace literals {
  Integer operator "" _I (const char *);
}

// Infinite precision integer 
class Integer {
  public:

  // Basic constructor & destructor
   Integer ();
  ~Integer ();

... rest of the interface ...

  // Literal operator
  friend Integer literals::operator "" _I (const char *);

  private:

  struct Detail;
  std::unique_ptr<Detail> detail;

};

用户使用 using namespace Lites; 引入运算符仅当他们想要时才声明。 (实际上,所有这些都在父名称空间中,但您明白了)。

In case it helps with syntax, here is how I declare a friend user-defined literal operator in a class, where the operator itself is in a namespace:

class Integer;
namespace literals {
  Integer operator "" _I (const char *);
}

// Infinite precision integer 
class Integer {
  public:

  // Basic constructor & destructor
   Integer ();
  ~Integer ();

... rest of the interface ...

  // Literal operator
  friend Integer literals::operator "" _I (const char *);

  private:

  struct Detail;
  std::unique_ptr<Detail> detail;

};

Users pull in the operator with a using namespace literals; statement only if they want it. (And, actually, all of this is in a parent namespace, but you get the idea).

寄意 2024-12-10 11:17:36

按照标准,是的,好友声明应该是合法的。
顺便说一句,该名称对于用户代码来说很好,因为即使在全局命名空间中它也以下划线开头。

友元声明将允许操作员访问类私有数据。

我开始质疑友元文字运算符的用处。由于用户定义的运算符只能有几个参数列表,因此无法将类放入参数中。因此,现在可以通过参数相关查找来找到正确的函数。我说得对吗?

According to the standard, yes, a friend declaration should be legal.
By the way, the name is fine for user code since it starts with an underscore even in global namespace.

The friend declaration would allow the operator to access class-private data.

I am beginning to question the usefulness of friend literal operators. Because the user-defined operators can only have a few argument lists there is no way to put the class in the arguments. So there is now way for argument dependent look-up to find the right function. Am I right?

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