C++14 自动 lambda 可以接受 Obj<std::tuple<void> > -- 但模板函数不能?
C++14 auto lambda can accept Obj<std::tuple<void> > -- but template functions cannot?
下面是一个程序,完全演示了我所看到的问题。
首先,我从一个使用其他类型的分组定义的对象开始,我开始使用 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...> > {
};
这些类型的"分组"结构在可变参数递归中经常使用,并且它们永远不会被创建/使用。 只是为了对模板参数进行分组。
但是,我"希望"对象"的签名由"用户期望"的类型/名称组成。
基本上,当std::tuple
用于"分组"时,我正在尝试任何可能的方式传递这些对象之一,并且只能找到一种方法:自动 lambdas。
谁能解释一下:
为什么"自动"λ可以为此工作?
关于延迟模板扣除? 喜欢差异黑白"自动"和"decltype(auto)"?
如何"设计"函数参数以接受这些对象之一。
-- 感谢大家对这个怪事的任何见解
例:
#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 messagen";
}
};
// 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。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中