【问题标题】:What's the intention behind such kind of template partial specialization?这种模板部分专业化背后的意图是什么?
【发布时间】:2021-01-28 22:49:18
【问题描述】:

当我尝试重构SGI STL源代码时,我看到了这段代码sn-p

template <class _Func, class _Ret>
struct _STL_GENERATOR_ERROR {
  static _Ret __generator_requirement_violation(_Func& __f) {
    return __f();
  }
};
template <class _Func>
struct _STL_GENERATOR_ERROR<_Func, void> {
  static void __generator_requirement_violation(_Func& __f) {
    return __f();
  }
};

用于检查相关函数签名类型的有效性。

这是我的问题: 为什么 SGI 故意将 void 的情况特化为返回类型?

template <class _Func, class _Ret>
struct _STL_GENERATOR_ERROR {
  static _Ret __generator_requirement_violation (_Func& __f) {
    return __f();
  }
};

void hello() {}

int main(int argc, char const *argv[])
{
  void (*ptr)() = &hello;
  _STL_GENERATOR_ERROR<void(*)(), void>::__generator_requirement_violation(ptr);
  return 0;
}

我的测试代码可以正常通过编译(clang/llvm/x86_64),并正常运行。

如果我在理解被剪断的原始代码或测试用例设计上犯了错误,请随时指出!

非常感谢。

问题已解决,但 跟进:为什么我的测试用例可以处理返回void类型的情况?

【问题讨论】:

  • 您询问的部分专业化是否实际使用return __f();__f();?似乎return __f(); 会使显式部分特化对通用实现变得多余(它们似乎与我相同)。
  • @FrançoisAndrieux 源代码使用return __f() 用于非无效返回的情况(__f() 是非无效返回),并简单地调用__f() 用于无效的情况-返回,但我想弄清楚的是,即使我使用return __f() 来处理返回无效的情况,它仍然可以很好地工作。

标签: c++ templates stl specialization sgi


【解决方案1】:

尽管自 ISO 981 以来,从返回 void 的函数返回 void 表达式是合法的 C++,但我们可以想象一些早期的 C++ 编译器没有实现该功能。

在这样的编译器上,通用模板会导致 _Ret = void 的错误:

template <class _Func, class _Ret>
struct _STL_GENERATOR_ERROR {
  static _Ret __generator_requirement_violation(_Func& __f) {
    return __f();
  }
};

这就是为什么我们可以猜测添加了一个特化(STL ):

template <class _Func>
struct _STL_GENERATOR_ERROR<_Func, void> {
  static void __generator_requirement_violation(_Func& __f) {
    __f();
  }
};

1)

[stmt.return]/3

带有 "cv-void" 类型表达式的 return 语句 只能在带有 return type-of-cv-void 的函数中使用;表达式在函数返回给它的调用者之前被计算。

source (p.98)

【讨论】:

  • 我没有注意到这是实际上一个 STL 问题。部分特化可能还有一个用例,允许将带有_Ret 的函数用作void,而_Func 是具有非void 返回类型的函数类型。这样,当返回值被忽略时,您可以使用具有任何返回类型的函数。但是,我不确定模板的实际用途,因此这种情况可能实际上并不相关。
  • @FrançoisAndrieux 你是对的。这个猜测本身就值得回答。
  • OP 的问题显示模板专业化返回为return __f();。这对我来说似乎是一个错误,但如果是这种情况,那么我提出的用例将不起作用。我留下了评论希望得到澄清。
  • @FrançoisAndrieux 如果other source 是对的,那就是错字了。
猜你喜欢
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
相关资源
最近更新 更多