【问题标题】:Deduce template parameter for a template function pointer with default template parameter使用默认模板参数推断模板函数指针的模板参数
【发布时间】:2021-11-01 00:25:38
【问题描述】:

虽然这个问题看起来有点令人困惑。代码很简单:

template <typename T>
void tfunc(T&& getter)
{

}

template <typename T = void>
void voidfunc()
{}

int main() {
    tfunc(&voidfunc);   // error: could not deduce template argument for 'T'
    tfunc(&voidfunc<int>); // ok
    voidfunc(); // calling using default template parameter is ok.
}

clang 11 和 msvc visual studio 2019 16.7 都报错。 为什么我需要显式指定模板参数?

背景

  • 该参数是一个虚拟参数,只是为了将voidfunc 的实例化延迟到使用它的位置。类型并不重要。
  • &amp;voidfunc被clangAST生成的一些代码使用,否则我需要调整生成器以编写&amp;voidfuc&lt;&gt;,如果它是一个模板。
  • __declspec(property(put=voidfunc)) 这个 clang/msvc 扩展需要 voidfunc 而不是 voidfunc&lt;&gt;

如果给定的函数是模板,我已经调整了生成器以输出 @Jarod42 所说的 &amp;voidfunc&lt;&gt;。它现在有效。

【问题讨论】:

  • tfunc(&amp;voidfunc&lt;&gt;); 如果你想使用默认值也可以。
  • 请在问题中包含完整的错误消息。这里没有错误godbolt.org/z/oaKfsxfnd(虽然这可能是 gccs 错误)
  • @463035818_is_not_a_number clang 和 msvc 都抱怨错误我已经更新了问题
  • voidfunc 是函数模板,没有指向函数模板的指针。
  • @Evg 没有,但有[temp.deduct.funcaddr]

标签: c++ templates c++17 language-lawyer c++20


【解决方案1】:

如 cmets 中所述,这种情况在 C++20 之前的标准中并不清楚,在哪里是 cleaned up,以便更好地支持约束函数的新特性。新规范在以前的语言版本中是有意义的(忽略约束的可能性),因此希望实现最终将在任何地方支持这种用法。

【讨论】:

    【解决方案2】:

    已默认模板参数的模板参数,不参与模板类型推导。 这就是为什么您必须为 voidfunc 显式提供模板参数的原因。

    Nicolai Josuttis 在他的 2017 cppcon 演讲“琐碎类的移动语义的噩梦”中解释了这一点:

    https://www.youtube.com/watch?v=PNRju6_yn3o&list=RDCMUCMlGfpWw-RUdWX_JbLCukXg&index=2

    【讨论】:

    • 请考虑编辑此链接以专门链接到说话者拥有此内容的时间戳,并删除查询字符串的播放列表参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    相关资源
    最近更新 更多