【发布时间】:2022-01-01 12:17:42
【问题描述】:
我正在开发一个程序,其中一些数据是静态分配的,而一些是动态分配的。现在我想要另一种类型,可以使用该类型的任何模板作为其参数来调用。
#include <array>
#include <vector>
template <int size> class Foo {
std::array<int, size> data;
public:
int& operator[](std::size_t idx) {return data[idx];}
};
template <> class Foo<-1> {
std::vector<int> data;
public:
int& operator[](std::size_t idx) {return data[idx];}
};
// option 1- polymorphism
struct FooCaller {
virtual void operator()(Foo data) = 0; // how would I make this work with both forms of Foo?
};
// option 2- generic programming
template <class T> concept CanCallFoo = requires (const T& t) {
t(std::declval<Foo&>()); // how do I ensure that this can call any overload of Foo?
};
这两种方法都可以,但我不知道该怎么做。因为完整的代码更复杂,我宁愿不要让两个 Foos 都从一个基类继承。
【问题讨论】:
-
看看
std::span,它对已知大小和运行时大小做了类似的事情。 -
struct FooCaller { template<int _S> void operator()(Foo<_S> data){...} }适合你吗? -
@Lux 命名
_S将导致未定义的行为。 -
@JDługosz 啊,谢谢你抓住了我!不幸的是,我似乎无法再编辑该评论,但对于任何想知道为什么它是 UB 的人,在 C++ 中,以
__或_[capital letter](以及其他)开头的标识符被保留(通常用于编译器或stdlib),因此,如果您使用它们,可能会出现一些不稳定的行为。有关更多信息,请参阅here(部分:“声明中”)!