提问人:Oliver Hawker 提问时间:8/30/2023 更新时间:8/30/2023 访问量:50
将参数包传递给从返回类型中扣除模板的功能
Pass parameter pack to function with template deduction from return type
问:
我正在编写一个对象分配器,我想按以下方式调用它:
T result = factoryObject.construct(argA, argB, argC);
我目前有这个设计,它有效......
class Factory {
void* memPool_;
template <typename Tret, typename... Args>
Tret construct(Args&&... args) {
Tret::methodA(std::forward<Args&&>(args));
Tret::Tret(memPool_, std::forward<Args&&>(args);
}
}
...只要我用:
T result = factoryObject.construct<T>(argA, argB, argC);
我希望能够在没有明确指定的情况下做到这一点。 可能会变得非常复杂,我需要在初始化器列表中内联使用这个工厂。我还需要在构造函数初始化器列表中使用它,所以我不能调用(我只需要它根据它正在构造的内容来推断返回类型)。T
T
auto result = factory.construct<T>()
我尝试使用 operator() 技巧推断类型(根据 https://stackoverflow.com/a/2613010/4649183):
public:
template <class T>
operator T() { return T(); }
};
class GC {
public:
static Allocator Allocate() { return Allocator(); }
};
int main() {
int p = GC::Allocate();
}
...但这不允许我传递参数(因为不能接受参数)。我尝试将元组存储为 的成员,将元组重新打包到参数包中,并使用元组到参数包问题中提出的逻辑分别调用 operator(),但是 operator()
Args&& args
Allocator
- 据我所知,这实际上无法存储对参数的引用(这是有道理的,因为编译器不知道我不会让原始参数超出范围)
- 最终的解决方案是如此复杂,以至于我一定是走错了路。
我能做些什么?
答:
5赞
Jarod42
8/30/2023
#1
你应该拥有所有部分。只需要正确组装它们。代码应类似于:
template <typename...Ts>
struct Constructor
{
Constructor(void* memPool, Ts... args) :
memPool{memPool},
args{std::forward<Ts>(args)...}
{}
template <typename T>
operator T() && {
return std::apply(
[this](auto&&... args) {
T::methodA(std::forward<Args&&>(args));
return T::T(memPool_, std::forward<Args&&>(args);
},
args);
}
void* memPool_;
std::tuple<Ts...> args;
};
class Factory {
void* memPool_;
template <typename... Args>
Constructor<Args&&...> construct(Args&&... args) {
return {memPool_, std::forward<Args>(args)...};
}
};
评论
0赞
Oliver Hawker
8/30/2023
这太棒了,谢谢!我一知半解这是如何工作的,但已经对其进行了修改,以使用 l 值和 r 值的各种组合对其进行测试,并且效果非常好。我将研究并了解它是如何工作的,但这似乎解决了我的问题。非常感谢您的快速回复!
0赞
Jarod42
8/30/2023
@NathanOliver:已使用左值/右值引用进行修复。Constructor<Args&&...>
Ts
0赞
NathanOliver
8/30/2023
啊哈,这就是我所缺少的。
评论
return
T
可以变得非常复杂,然后给它一个别名。std::forward<Args&&>
std::forward<Args>
args
T
auto
auto result = factoryObject.construct<T_or_alias>(...)