gpt4 book ai didi

C++14 auto lambda 可以接受 Obj>——但模板函数不能?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:23:41 24 4
gpt4 key购买 nike

下面是一个程序,它完全演示了我所看到的问题。

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

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

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

我想传递这些对象,也许复制/移动它们......它们的数据成员都不是这些类型的元组。事实上,我可以使用上面的空对象定义重现该问题。

可以让它工作,使用类似的东西:

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

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

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

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

基本上,当 std::tuple 用于“分组”时,我正在尝试用任何可能的方式传递这些对象之一,但只能找到一个方式:自动 lambda。

谁能解释一下:

  1. 为什么“自动”lambda 可以为此工作?

    关于延迟模板推导的事情?比如 diff b/w“auto”和“decltype(auto)”?

  2. 如何“设计”函数参数以接受这些对象之一。

-- 感谢大家对这个怪事的任何见解

例子:

#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;
}

最佳答案

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

如果被调用的东西没有命名函数或函数模板,则不执行依赖于参数的查找;因此使用 lambda 有效 - takeobj_lambda是一个对象。

如果您使用限定调用 ( ::takeobj(oval) ),或括号 takeobj ( (takeobj)(oval) ),然后代码编译。这两者都会禁用 ADL。

关于C++14 auto lambda 可以接受 Obj<std::tuple<void>>——但模板函数不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35028496/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com