替代用什么不失败

时间:2019-04-11 17:16:34

标签: c++ sfinae

我有一个使用模板的Jav :: String类。

 class String
 {
  String();
  String(std::size_t);

  template <class ITER_WRAP>
  String(const ITER_WRAP &iterator_begin_end);
 }

我希望当我用带符号整数调用字符串时,如MAX_PATH一样,它将调用std :: size_t又名unsigned int重载;因为我期望替换不会失败!基本上,一个int没有开始,结束元素,因此替换应该失败,并且该功能不应成为候选功能的一部分。

但是,令我感到恐惧的是,我得到了一个编译错误,const int没有开始或结束成员。

什么时候是替代失败,什么时候不是失败。它仅适用于类型吗?

1 个答案:

答案 0 :(得分:2)

替换失败不是错误(SFINAE)仅与重载解析期间替换模板参数有关。这基本上意味着,如果在弄清楚要调用哪个函数的过程中替换推导的模板参数会导致在某个地方生成无效的类型或表达式,那么这不会导致编译失败,而只会导致相应的错误。函数不再被视为函数调用的潜在候选者。只有出现在函数模板的声明(或部分类或变量模板的特殊化)中的内容才可以受到SFINAE的约束。函数模板定义的潜在实例化是在确定要确切调用哪个函数之后发生的。如果在函数模板的定义实例化过程中替换模板参数导致无效构造,那么这种替换失败将很可能是错误。

在您的特定情况下,有两个选择

String(std::size_t);

template <class ITER_WRAP>
String(const ITER_WRAP &iterator_begin_end);

使用参数String类型的int构造函数的调用将选择模板专用化String<int>,因为调用String(std::size_t)需要积分提升,而转换排名却更差比String<int>给您的精确匹配…