AFT(缩写函数模板)有什么争议?

What's so controversial about AFTs (Abbreviated Function Templates)?

为什么这个功能如此有争议?我看到它没有与 Concepts TS 的其余部分一起合并到 C++20 中。通过网络搜索,除了可以应用于几乎所有新 C++ 功能的通用参数外,我找不到合理的参数。

人们害怕什么?那里可能有什么陷阱?毕竟,我们已经有了通用的 lambda。

考虑以下程序:

void foo(Name&& x) {
    static int counter = 0;
    ++counter;
    x.func<int>(); // #1
}

Name x = ...;
foo(x); // #2

template <typename T> void some_algorithm(T);
some_algorithm(foo); // #3

如果Name是一个类型,那么只有一个名为counter的静态变量,foo是一个接受右值引用的函数,[=16=中的调用] 很好(假设存在这样的成员函数),#2 中的调用格式错误,因为 x 是左值,#3 中的调用格式正确,因为 foo 只是衰减到一个函数指针。

如果Name是一个概念,每个类型实例化一个静态变量(包括不同的值类别),foo是一个函数模板,只能在头文件中定义,调用in #1 格式错误,因为您需要一个额外的 template 关键字, #2 中的调用格式正确,因为我们只是推导出一个左值引用参数,而对 [=19 的调用=] 格式错误,因为您不能传入这样的函数模板 - 您需要将其包装在 lambda 或其他东西中。

这在每个参数上叠加:

void foo(Name&&, OtherName&&);

名称可以是没有标记的类型或概念。

一切都基于事物 Name 的类别。那是……很大的不同(请注意,以上也不是 完整的 差异列表,只是我能立即想到的最大差异),并且有人担心它太多而没有相应的好处。

另见 P0696


请注意,其中 none 适用于通用 lambda 和 auto,因为 auto 是一个关键字,因此 void foo(auto&& x) 显然是一个函数模板。这是一个清晰的标记,可以避免所有这些歧义。

另请注意,P1141 建议对 AFT 使用相同的句法标记:

void f(Sortable auto& x);

考虑到似乎每个就此主题大声发表意见的人都是该论文的合著者,我认为它的成功几率高于平均水平。