5

operator "" (...)将 an 定义为友元函数是否可能和/或有用?

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

我正在考虑“有用”,特别是因为operator ""应该只在命名空间中定义的规则——尤其是因为以开头的标识符_被保留在全局命名空间中。这friend违反了这个规则吗?所以,这种不完全的封装不会有任何好处,对吧?

4

3 回答 3

2

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

declarator-id 为 literal-operator-id 的声明应是命名空间范围函数或函数模板的声明(它可以是友元函数 (11.3))、函数模板的显式实例化或特化,或使用声明(7.3.3)。

如果朋友也在命名空间范围内声明,那么在类或命名空间范围内的定义没有区别。请注意,在命名空间范围内没有定义要求,您的问题目前措辞是断言的。

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

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

于 2011-09-11T02:11:37.010 回答
1

如果它有助于语法,这里是我如何在一个类中声明一个朋友用户定义的文字运算符,其中运算符本身位于命名空间中:

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 literals;仅在需要时才使用语句引入运算符。(实际上,所有这些都在父命名空间中,但你明白了)。

于 2011-12-05T00:48:27.173 回答
0

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

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

我开始质疑友元文字运算符的用处。因为用户定义的运算符只能有几个参数列表,所以无法将类放在参数中。所以现在有一种方法可以让参数相关的查找找到正确的函数。我对吗?

于 2011-09-09T19:55:16.417 回答