我有以下定义(不完整,不起作用):
template<typename T, std::function<Args(Context&)>... Funcs>
struct constructor
{
T construct(Context& ctx)
{
return T(Funcs(ctx)...);
}
};我想要的是一个模板化的类-第一个参数是构造的类型,下面的所有函数都是要调用的函数,然后调用带有std::function的用户模板来为T类型的构造函数生成值。
除了捕获函数的返回类型之外,我看不出有可能使这段代码工作。我希望用户像这样使用它:
std::function<int(Context&)> ind = [](Context&) {return 2;};
Constructor<int, ind> c;
// c.construct(...) returns 2 by calling the constructor int(int) with argument
// ind(ctx) - which returns 2.发布于 2014-12-11 16:01:54
这大概就是你要找的东西。请记住,std::function不能成为模板参数。
template <typename R> using Generator = std::function<R (Context&)>;
template <typename T, typename Generators, std::size_t... Is>
T constructImpl(Context& ctx, const Generators& generators,
std::index_sequence<Is...>) {
return T(std::get<Is>(generators)(ctx)...);
}
template <typename T, typename... Args>
class Constructor {
std::tuple<Generator<Args>...> generators;
public:
Constructor(Generator<Args>... generators)
: generators(std::move(generators)...)
{}
T construct(Context& ctx) {
return constructImpl<T>(ctx, generators,
std::index_sequence_for<Args...>());
}
};用法:
Constructor<int, int> c([](Context&) { return 2; });
int i = c.construct(context);
assert(i == 2);发布于 2014-12-11 16:56:09
类型不能依赖于运行时数据。
调用std::function<X(Y)>需要运行时数据。因此,您的类型不能依赖于std::function<X(Y)>,因此不能将该类型用作模板参数。
现在,它可以依赖于指向全局对象的指针:有趣的是,就C++而言,这并不是运行时状态。
因此,您的设计是有根本缺陷的。
如果您想要一个返回2的函数,这是可行的:
template<class...ignored>
struct Constructor {
template<class... also_ignored>
Constructor(also_ignored&&...) {}
template<class... also_ignored>
int construct(also_ignored&&...) { return 2; }
};这将通过OP中描述的单元测试,但不能将ind传递给Constructor,因为这是不合法的。但是,将其从类型签名中删除并不重要。
如果你想要更多的能量,我们可以这样做:
template<class T, class... Functors>
struct Constructor {
T construct( Context& ctx ) {
return T( Functors{}( ctx )... );
}
};在这种情况下,您需要无状态函数对象:
struct ind { int operator()(Context&)const{return 2;} };就像std::map需要无状态比较对象一样。
如果您的函数对象需要状态,那么您需要存储它们的副本,以便Constructor访问(可能在Constructor中),并且可能需要元组和索引技巧来存储它们。(“索引技巧”是一个有用的谷歌)
发布于 2014-12-11 16:13:15
我认为您的Construct可以只是一个函数:
template <typename T, typename... Funcs>
T construct(Context& ctx, Funcs... funcs) {
return T(funcs(ctx)...);
}在您的示例中,其用法可以是:
int x = construct<int>(ctx, [](Context& ) { return 2; });https://stackoverflow.com/questions/27426805
复制相似问题