查找模板相等运算符

nih*_*hit 2 c++ templates

我想编写一个代理类,该类具有模板值,并且可以与可以与模板进行比较的任何类进行比较。

template <class T>
class Proxy {
public:
  Proxy(T value) : _value(value) {}

  template <class U> // this should exist only if the T == U operator is defined
  bool operator==(U const& other) const  { return _value == other; }

  template <class U> // this should exist only if U == T is defined
  friend bool operator==(U const& first, Proxy<T> const& second) const  { return first == second._value; }

private:
  T _value;
};
Run Code Online (Sandbox Code Playgroud)

例如,由于这是合法代码:

bool compare(std::string first, std::string_view second) {
  return first == second;
}
Run Code Online (Sandbox Code Playgroud)

我也希望这是合法的:

bool compare(std::string first, Proxy<std::string_view> second) {
  return first == second;
}
Run Code Online (Sandbox Code Playgroud)

但只是为了澄清起见,这应该适用于可以比较的任何类,或者可以进行隐式转换以便进行比较。我可以定义一个条件模板来检查这两种情况吗?

Sto*_*ica 5

由于您的标准本质上是像like这样的表达式_value == other是否格式正确,因此您可以仅依赖表达式SFINAE对其进行测试。

  template <class U> // this should exist only if the T == U operator is defined
  auto operator==(U const& other) const -> decltype(_value == other)
  { return _value == other; }

  template <class U, std::enable_if_t<!std::is_same<U, Proxy>::value, int> = 0> // this should exist only if U == T is defined
  friend auto operator==(U const& first, Proxy const& second) -> decltype(first == second._value)
  { return first == second._value; }
Run Code Online (Sandbox Code Playgroud)

它可能不是很干,因为我们需要重复两次表达式,但这是执行SFINAE的相当简单的方法,这是一个主要优点。

要注意的另一件事是,我们不希望递归地考虑第二个重载,这可能在比较两个代理时发生。因此,我们需要另一个SFINAE条件,enable_if用来阐明老式的方式,以在Ua 为时放弃重载Proxy。这依赖于C ++ 14功能,通过该功能可以按声明顺序检查替换。将其放在首位可防止递归first == second._value