当前位置: 首页 > 知识库问答 >
问题:

C++14自动lambda可以接受obj--但是模板函数不能?

姜正初
2023-03-14

下面是一个完整演示我所看到的问题的程序。

首先,我从一个使用其他类型的分组定义的对象开始,我开始使用std::tuple<>来管理分组。

template <typename> class object;
template <typename... Rs> class object<std::tuple<Rs...> > {
};

我打算这些对象能够将void类型分散在“包”中。我已经意识到无法“实例化”这种类型的元组(请参见std::tuple中的Void类型)

template <typename... Rs> struct TGrp {};

template <typename> class object;
template <typename... Rs> class object<TGrp<Rs...> > {
};

这些类型的“分组”结构在可变递归中经常使用,它们永远不会被创建/使用。只是为了对模板arg进行分组。

但是,我“希望”对象的签名由“用户期望的”类型/名称组成。

基本上,当std::tuple用于“分组”时,我尝试了传递这些对象的任何可能方法,但只能找到一种方法:自动lambdas。

>

  • 为什么“自动”lambda能起作用?

    关于延迟模板扣减的事?就像不同的B/W“自动”和“decltype(自动)”?

    如何“设计”一个函数参数来接受这些对象之一。

    示例:

    #include <tuple>
    #include <iostream>
    
    #define GRP std::tuple      // IF 'tuple' used:  compile error where noted below
    //#define GRP TGrp          // if THIS is used:  all works, and TGrp() is never constructed
    
    
    // Grouping mechanism
    template <typename... Ts> struct TGrp {
        TGrp() {
            std::cout << "Never printed message\n";
        }
    };
    
    
    // MAIN OBJECT (empty for forum question)
    template <typename> class object;
    template <typename... Rs> class object<GRP<Rs...> > {
    };
    
    
    
    // Regular function                  (does NOT work)
    void takeobj(object<GRP<void> >& obj) { (void)obj; }
    
    // Lambda - taking anything...       (only thing I could make WORK)
    auto takeobj_lambda = [](auto obj) { (void)obj; };
    
    // Template func - taking anything   (does NOT work)
    template <typename T> void takeobj_templ_norm(T obj) { (void)obj; }
    template <typename T> void takeobj_templ_clref(const T& obj) { (void)obj; }
    template <typename T> void takeobj_templ_lref(T& obj) { (void)obj; }
    template <typename T> void takeobj_templ_rref(T&& obj) { (void)obj; }
    
    
    int main()
    {
        object<GRP<void> > oval;
    
        //takeobj(oval);                  // <--    causes compile error
    
        takeobj_lambda(oval); // works
    
        //takeobj_templ_norm(oval);       // <--    also error
        //takeobj_templ_clref(oval);      // <--    also error
        //takeobj_templ_lref(oval);       // <--    also error
        //takeobj_templ_rref(oval);       // <--    also error
        return 0;
    }
    

    编辑:添加修剪后的复制:

    #include <tuple>
    
    
    // MAIN OBJECT (empty for forum question)
    template <typename> class object;
    template <typename... Rs> class object<std::tuple<Rs...> > {
    };
    
    // Regular function                  (does NOT work)
    void takeobj(object<std::tuple<void> >& obj) { (void)obj; }
    
    // Lambda - taking anything...       (only thing I could make WORK)
    auto takeobj_lambda = [](auto obj) { (void)obj; };
    
    
    int main()
    {
        object<std::tuple<void> > oval;
    
        //takeobj(oval);                  // <--    causes compile error
        takeobj_lambda(oval); // works
    
        return 0;
    }
    
  • 共有1个答案

    夏朝
    2023-03-14

    std::tuple 对象 > 的关联类,因此在执行参数相关查找的非限定调用中,将实例化std::tuple 以查找任何可能已内联定义的friend函数。此实例化会导致错误。

    如果被调用的对象没有命名函数或函数模板,则不执行参数相关的查找;因此,使用lambda Works-takeObj_lambda是一个对象

    如果您使用限定调用(::takeobj(oval)),或者在takeobj((takeobj)(oval))中加上括号,那么代码将编译。这两种方法都禁用ADL。

     类似资料:
    • 我试图理解下面代码中的编译器错误。我有一个variadic模板函数,它接受具有指定类型的lambda,试图调用该函数会导致模板由于不匹配而不被视为有效的候选模板。 如果我将声明更改为不变: 然后它为上面的玩具示例工作,但对于真正的问题,我需要任意的论点。我是不是缺少了什么,或者还有什么方法可以做到这一点? 编辑:这被错误地标记为重复,我相信--受骗者没有回答我所问的问题。这个问题特别与这里的var

    • 假设我们有我的代码的简化版本: 我试图将lambda函数作为参数传递给函数,但只有当我将lambda显式分配给特定的类型时,它才起作用。这是可行的: 上面的例子是可行的,但我想实现下面的例子,因为审美的原因,不知道这是否可能: 我唯一的要求是应该接受带有模板化返回类型的lambda和函数,以及带有特定类型的输入参数,例如。

    • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

    • 我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误

    • 问题内容: 我正在尝试将用c ++编写的并行排序包装为模板,以将其与任何数字类型的numpy数组一起使用。我正在尝试使用Cython来做到这一点。 我的问题是我不知道如何将指向正确类型的numpy数组数据的指针传递给C ++模板。我相信我应该为此使用融合dtypes,但是我不太了解如何使用。 .pyx文件中的代码如下 过去,我对所有可能的dtype进行了丑陋的for循环处理,但我相信应该有更好的方

    • 我想使用一个模板函数扩展默认的Golang模板函数,该模板函数呈现另一个Golang模板,而该模板也应该可以访问相关函数。 下面的演示案例应该创建一个< code>include模板函数,该函数呈现一个给定的模板,该模板也可以包含相同的< code>include函数。然而,这个例子(理所当然地)引发了一个初始化周期错误。 Golang 模板函数是否可以在引用自身时渲染另一个模板? https:/