Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ lambda函数参数与模板函数没有匹配的函数调用_C++_Lambda_Variadic Templates_C++20 - Fatal编程技术网

C++ lambda函数参数与模板函数没有匹配的函数调用

C++ lambda函数参数与模板函数没有匹配的函数调用,c++,lambda,variadic-templates,c++20,C++,Lambda,Variadic Templates,C++20,试图将lambda函数传递给模板工厂函数,而模板工厂函数是根据传递函数的函数参数进行模板化的,这会导致gcc-10.2.0报告调用“test(main():)”时没有匹配的函数。 当我在lambda函数前面添加一个+强制转换为函数指针时,它似乎确实起作用,但我不明白为什么需要这样做。为什么转换不会自动发生?有什么办法可以让这一切顺利进行吗 我还尝试了std::function test\u func作为make\u test声明中的参数,但是这给了我相同的调用错误时没有匹配的函数 #包括 模板

试图将lambda函数传递给模板工厂函数,而模板工厂函数是根据传递函数的函数参数进行模板化的,这会导致gcc-10.2.0报告调用“test(main():)”时没有匹配的函数。

当我在lambda函数前面添加一个
+
强制转换为函数指针时,它似乎确实起作用,但我不明白为什么需要这样做。为什么转换不会自动发生?有什么办法可以让这一切顺利进行吗

我还尝试了
std::function test\u func
作为
make\u test
声明中的参数,但是这给了我相同的
调用
错误时没有匹配的函数

#包括
模板
结构测试类型{
测试类型(无效(目标…){};
};
模板
测试类型制造测试(无效测试功能(TArgs…){
返回测试类型{test\u func};
}
int main(){

auto test_object=make_test([](int a,double b){std::cout为了支持传递给工厂的各种可调用函数(例如,有状态lambda或函数指针),您的
test_type
构造函数应该接受某种类型的擦除函数类型,如
std::function

(这是voider模式的常见设置。我们可以通过概念和约束来实现这一点,但我觉得太懒了,无法查找语法,可能以后再查)

常规函数指针专门化

template<class Ret, class... Args>
struct infer_test_type<Ret(*)(Args...)>
{
    using type = test_type<Args...>;
};
现在只需要涵盖另外两种情况

可调用对象

  • 这些将具有运算符()(或
    const
    或不)
我将从一个顶级特征开始检测
operator()
的存在,并将
operator()的类型输入到另一个特征中

顶级特质:

// if T is a callable object
template<class T>
struct infer_test_type<T, std::void_t<decltype(&T::operator())>>
{
    using type = typename infer_test_type<decltype(&T::operator())>::type;
};
(如果我们想变得更聪明一点,可能可以将这两种方法结合起来,在调用之前去掉高层的
const
,但我认为这更清楚)

现在,我们应该能够为非泛型可调用函数(无泛型lambda或模板化
运算符()
函数)推断出合适的
测试类型:

使用非常量
运算符()进行的测试

struct my\u可调用
{
void运算符()(int,double)//非常量
{
}
};
// ...
静态断言(std::is_same_v);
用你的lambda进行测试:

auto lambda = [](int a, double b) { std::cout << a << b << "\n"; };
static_assert(std::is_same_v<infer_test_type_t<decltype(lambda)>, test_type<int, double>>);

auto lambda=[](inta,double b){std::cout有帮助:@AndyG有没有
std::function
,我想OP是在问如何从lambda推断参数类型。@RichardCritten因为
auto test\u object=test\u type{[](inta,double b){std::cout推断指南也可以添加:
template test\u type(T&&)->推断测试类型
@Jarod42:不幸的是,根据[temp.decrete.guide],扣减指南中
->
右侧的简单模板id中的模板名称必须与类的模板名称匹配,由于需要推断变量参数,我看不到一个好的解决方法。事实上:-/Sad…谢谢!对于看起来如此简单的东西来说,这是一个大混乱…你提到了概念和约束,这会使它变得更好吗?@wich,不幸的是,不多。我们必须先构建一些东西。可重用的东西,但如果你不这么做,我会如果你做了很多元编程,那可能就不值得了
template<class T>
using infer_test_type_t = typename infer_test_type<T>::type;
void foo(int, double){}
// ... 
static_assert(std::is_same_v<infer_test_type_t<decltype(&foo)>, test_type<int, double>>);
template<class T>
auto make_test(T&& callable) -> infer_test_type_t<T>
{
    return infer_test_type_t<T>{std::forward<T>(callable)};
}
// if T is a callable object
template<class T>
struct infer_test_type<T, std::void_t<decltype(&T::operator())>>
{
    using type = typename infer_test_type<decltype(&T::operator())>::type;
};
// if operator() is a const member function
template<class T, class Ret, class... Args>
struct infer_test_type<Ret(T::*)(Args...) const>
{
    using type = test_type<Args...>;
};

// if operator() is non-const member function
template<class T, class Ret, class... Args>
struct infer_test_type<Ret(T::*)(Args...)>
{
    using type = test_type<Args...>;
};
struct my_callable
{
    void operator()(int, double) // non-const
    {
    }
};

// ...
static_assert(std::is_same_v<infer_test_type_t<my_callable>, test_type<int, double>>);
auto lambda = [](int a, double b) { std::cout << a << b << "\n"; };
static_assert(std::is_same_v<infer_test_type_t<decltype(lambda)>, test_type<int, double>>);
make_test([](int a, double b) { std::cout << a << b << "\n"; });