传递已推导的类型作为回调的参数类型

Pass on already deduced type as parameter type for a callback

所以我正在尝试执行以下操作

int x = 123;
myFunction(x, [](auto y) {
    std::cout << y;
});

myFunction定义为

template <typename T>
void myFunction(T val, void(*callback)(T)) {
    callback(val);
} 

当尝试编译代码时,clang 给我错误 could not match 'void (*)(T)' against '(lambda at ...)'。我发现这是因为您无法从 lambda 中推断出类型。

所以这实际上没问题,因为我真正想要的是 callback 的参数类型是从 myFunction.

val 参数推导出来的类型

所以我的问题简单地说,是否有可能以某种方式将 callback 参数排除在推导之外,而只使用 val 的推导类型?

is it possible somehow to exclude the callback parameter from being deduced and instead just use the deduced type of val?

当然可以。

如果你定义这样的东西

template <typename T>
struct self
 { using type = T; };

你可以定义myFunction()如下

template <typename T>
void myFunction(T val, void(*callback)(typename self<T>::type)) {
    callback(val);
} 

现在 Tval 推导出来并用于 callback

从C++20开始,可以避开self定义,使用新引入的std::type_identity_t

template <typename T>
void myFunction(T val, void(*callback)(std::type_identity_t<T>)) {
    callback(val);
} 

一个选项(还有几个选项)是将可调用项作为模板参数传递,并允许模板为您处理一些细节 - 例如:

template <typename T, typename FUNCTOR>
void myFunction(T val, FUNCTOR callback) {
    callback(val);
}

// Note: could be a const ref:
//void myFunction(T val, const FUNCTOR &callback) {


int main()
{

    int some_int{1};
    myFunction(some_int, [](auto y){ std::cout << y << std::endl; });

    float some_float{1.1f};
    myFunction(some_float, [](auto y){ std::cout << y << std::endl; });

    return 0;
}

这里有完整示例(遵循您的代码 - 但可以进一步整理):https://godbolt.org/z/qr7T5GPd6