下面是一个程序,完全演示了我所遇到的问题。
首先,我从使用其他类型的分组定义的对象开始,开始使用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
用于“分组”,并且只能找到一种方式:自动lambda。
谁能解释:
为什么“自动” lambda可以做到这一点?
关于延迟模板推论的东西?像差异黑白“自动”和“ 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;
}
std::tuple<void>
是一个关联类的object<std::tuple<void>>
,因此,在其中进行参数相关的查找不合格的呼叫,std::tuple<void>
被实例化,以寻找任何friend
可能已定义的内联函数。此实例导致错误。
如果被调用的事物未命名函数或函数模板,则不执行依赖于参数的查找。因此使用lambda作品-takeobj_lambda
是一个对象。
如果您使用限定调用(::takeobj(oval)
)或括号takeobj
((takeobj)(oval)
),则将编译代码。这两个都禁用ADL。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句