- 已关闭**。此问题需要details or clarity。当前不接受答案。
- 想要改进此问题?**添加详细信息并通过editing this post阐明问题。
3天前关闭。
这篇文章是编辑和提交审查3天前。
Improve this question
我想使用一个fold表达式,但是这个函数只能和一个已知的参数包一起使用。
即
template <class... Types>
Foo fn_impl(Arg arg) {
// here, a fold expression involving Types... that returns a Foo
}
Foo fn(Arg arg) {
return fn_impl<Bar, Baz>(arg);
}
就这样,fn_impl
将永远不会再被使用。有没有什么方法可以让它变得更简洁?理想情况下,我希望在它的主体中编写fn
的实现,而不使用单独的实现函数(这会增加噪音,imo)。
我知道我可以用参数包中的类型手工"展开" fold表达式,但在本例中,使用fold表达式非常方便,可以使fn的实现不太冗长。
下面是一个完整的示例,请参见突出显示的QUESTION
注解:
#include <cassert>
#include <cstdio>
#include <memory>
struct Base {
virtual ~Base() {}
virtual const char *get_name() const = 0;
};
template <class Derived> struct Base_CRTP : public Base {
const char *get_name() const final {
return static_cast<const Derived *>(this)->name;
}
};
struct A : Base_CRTP<A> {
static constexpr const char *name = "A";
};
struct B : Base_CRTP<B> {
static constexpr const char *name = "B";
};
#define ITest_DERIVED_CLASSES A, B
// QUESTION: Can this be entirely moved into the definition of #1?
template <class IType, class... Types>
std::unique_ptr<IType> make_by_class_index___impl(int class_index) {
int i = 0;
std::unique_ptr<IType> ret;
([&] {
if (i++ == class_index)
ret = std::make_unique<Types>();
return ret != nullptr;
}() ||
...);
return ret;
}
// #1
std::unique_ptr<Base> make_by_class_index(int class_index) {
return make_by_class_index___impl<Base, ITest_DERIVED_CLASSES>(class_index);
}
template <class... Types> void print_pack_names() { (puts(Types::name), ...); }
int main() {
print_pack_names<ITest_DERIVED_CLASSES>();
puts("");
auto p = make_by_class_index(0);
assert(p != nullptr);
printf("p name: %s\n", p->get_name());
auto p2 = make_by_class_index(1);
assert(p2 != nullptr);
printf("p2 name: %s\n", p2->get_name());
auto p3 = make_by_class_index(99);
assert(p3 == nullptr);
}
1条答案
按热度按时间9ceoxa921#
在缺乏足够细节的情况下,让我们不失一般性地假设
Arg
是int
,Foo
、Bar
和Baz
定义如下:如果你可以使用C++20,你可以迁移a)一个包含fold表达式的变量函数和B)一个对site的调用到它,例如:
转换成一个泛型的立即调用的lambda,利用P0428R2(在C++20中引入)允许为泛型lambda模板头:
这看起来相当复杂,尤其是当你需要使用操作符名称语法来为泛型lambda提供显式的模板参数时,分离函数的方法对于未来的维护者来说更容易遵循。