具有先前模板参数类型的自动返回类型参数的函数类型的模板参数

Typ*_*eIA 5 c++ templates language-lawyer c++17

我有一个带有两个参数的模板:第一个是类型,第二个是带有参数的函数指针,其类型是第一个模板参数。这个 MCVE 有效:

void returnsVoid(int x) { }

template <typename T, void (*Func)(T)>
struct foo { void bar(T t) { Func(t); } };

int main(int, char *[]) {
    foo<int, returnsVoid> a; // ok
}
Run Code Online (Sandbox Code Playgroud)

但是,当我将第二个模板参数的返回类型更改为auto(如本相关问题中所述)时,出现错误:

void returnsVoid(int x) { }

template <typename T, auto (*Func)(T)>
struct foo {
    void bar(T t) { Func(t); }
};

int main(int, char *[]) {
    foo<int, returnsVoid> a; // error: unable to deduce ‘auto (*)(T)’ from ‘returnsVoid’
                             // note:   mismatched types ‘T’ and ‘int’
}
Run Code Online (Sandbox Code Playgroud)

为什么这不再适用于auto返回类型?

我在 Ubuntu Linux 机器上使用 g++ 9.3.0。类似的错误发生在 clang 10 中。

son*_*yao 2

这是gcc的bug。(错误 83417

auto当使用第一个模板参数T作为函数参数时,gcc 似乎无法推断出 的类型;您可以使用std::type_identity(C++20 起) 将其排除在模板参数推导之外。

// workaround for gcc
template <typename T, auto (*Func)(std::type_identity_t<T>)>
struct foo {
    void bar(T t) { Func(t); }
};
Run Code Online (Sandbox Code Playgroud)

居住

顺便说一句:Clang 10看起来运行良好。