正在访问一个不存在的成员,他不认为是一个“错误”就SFINAE是什么呢?

问题描述 投票:2回答:2

我实现了漂亮的印刷对过载:

template<typename P>
ostream &operator<<(ostream &os, const P &p) {
  using std::operator<<;
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

然而,在其存在的编译器有麻烦告诉它是否适用标准过载或我上面定义的,即使是在选择的时候应该是很明显的例子之一:

int main() {
  cout << "SFINAE sure is hard to grasp!\n";
}

error: use of overloaded operator '<<' is
      ambiguous (with operand types 'std::ostream' (aka 'basic_ostream<char>') and
      'const char [30]')

我不太明白是什么问题。该字符数组我想清晰地打印有没有firstsecond成员,因此,我的超载实例会导致错误。

不应SFINAE尝试执行替换,找出成员缺乏,并丢弃,结果呢?如果不是,为什么?

c++ templates sfinae
2个回答
6
投票

SFINAE重载期间的工作原理:

这条规则的函数模板重载时适用:当替换明确指定或推断类型模板参数失败,专业化是从设定的,而不是造成编译错误超载丢弃。

这意味着只有函数模板的签名即可生效SFINAE,实施将不会被选中。

您可以更改重载

template <typename T, typename = void>
struct pairable : std::false_type {};

// check whether type T has first and second members
template <typename T>
struct pairable<T, std::void_t<decltype(std::declval<T>().first),
                               decltype(std::declval<T>().second)>>
    : std::true_type {};

// the template parameter is the part of the signature of function template
template<typename P, std::enable_if_t<pairable<P>::value>* = nullptr>
ostream &operator<<(ostream &os, const P &p) {
  using std::operator<<;
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

LIVE


5
投票

SFINAE只适用于功能签名:即参数类型,返回类型,和限定符,如:const,非const。它并不适用于功能的实现。

在你的情况,函数签名的呼叫匹配。因此,该函数被实例化,并有望没有错误编译。

© www.soinside.com 2019 - 2024. All rights reserved.