[英]Literal type that can wrap a callable, e.g., function or member function
I would like to call a function F
with some fixed signature which itself wraps a call to a member function Foo::*p
of some class Foo
.我想用一些固定的签名调用 function
F
,它本身包含对某个 class Foo
的成员 function Foo::*p
的调用。 The member functions come in too flavours:成员函数也有不同的风格:
int* m1() {...}
, and, int* m1() {...}
,并且,template <typename T> void m2(T t) {...}
and there are two versions of F
(the second one being a template, of course) depending of what member function flavour there is. F
有两个版本(当然,第二个是模板)取决于成员 function 的风格。
The number of member function of Foo
and possible calls for F
is finite and known at compile time. Foo
的成员 function 的数量和对F
的可能调用是有限的,并且在编译时已知。 I was trying to do something along the following lines:我试图按照以下方式做一些事情:
struct Foo {
void m1(int) {}
int* m2() { return &x; }
int x = 0;
};
using FunT = std::function<bool(int)>;
FunT Make1(void(Foo::*pf)(int)) {
return [pf](int){return true;};
}
FunT Make2(int*(Foo::*pf)()) {
return [pf](int){return true;};
}
static std::array a = {
Make1(&Foo::m1),
Make2(&Foo::m2)
};
template <int i> FunT FunToCall() {
return a[i];
}
template <int... is> bool make_calls(Foo& foo, int arg) {
return (FunToCall<is>()(is)&& ...);
}
int main() {
Foo foo;
make_calls<0,1>(foo, 5);
}
which compiles and runs.编译并运行。
Now, if main
called make_calls<0,1,2>(foo, 5);
现在,如果
main
调用make_calls<0,1,2>(foo, 5);
the program will throw at run time—to prevent this I want to move the check to compile time by making both the array a
and the getter FunToCall
constexpr
.该程序将在运行时抛出 - 为防止这种情况,我想通过将数组
a
和 getter FunToCall
constexpr
移动到编译时。 Starting with array, however I hit a roadblock:从数组开始,但是我遇到了障碍:
<source>:37:29: error: the type 'const std::array<std::function<bool(int)>, 2>' of 'constexpr' variable 'a' is not literal
37 | static constexpr std::array a = {
| ^
In file included from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/array:95:12: note: 'std::array<std::function<bool(int)>, 2>' is not literal because:
95 | struct array
| ^~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/array:95:12: note: 'std::array<std::function<bool(int)>, 2>' has a non-trivial destructor
I understand the error and I've tried each and every way to come up with something that works but couldn't figure out a way.我理解这个错误,并且我已经尝试了各种方法来想出一些可行但无法找到方法的方法。
Is there a known idiom/pattern here that can be used here?这里有可以使用的已知习语/模式吗? More generally, any ideas how to make this work (so the out-of-bounds check happens at compile time)?
更一般地说,任何想法如何使这项工作(所以越界检查发生在编译时)?
As suggested by @Igor Tandetnik, a possible work-around is to use static_assert
inside of FunToCall
(since the std::array
size is a compile-time constant).正如@Igor Tandetnik 所建议的,一种可能的解决方法是在
FunToCall
内部使用static_assert
(因为std::array
大小是编译时常量)。 Would still like to know if the array can somehow be made constexpr
.仍然想知道数组是否可以以某种方式制成
constexpr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.