简体   繁体   English

可以包装可调用对象的文字类型,例如 function 或成员 function

[英]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

template <int i> FunT FunToCall() {
    static_assert(i < std::tuple_size_v<decltype(a)>);
    return a[i];
}

Demo .演示 The size of std::array is a compile-time constant even if the array itself is not constexpr . std::array的大小是编译时常量,即使数组本身不是constexpr也是如此。 It's part of the type.它是类型的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么成员函数需要'&'(例如在std :: bind中)? - Why does a member function needs '&' (e.g. in std::bind)? 没有匹配的 function 来调用:错误:必须使用 '.*' 或 '-&gt;*' 来调用指向成员 function 在 'f (...)' 中的指针,例如 '(... -&gt;* f) (...)' - No matching function to call: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (…)’, e.g. ‘(… ->* f) (…)’ 定义分段函数(例如多项式) - Defining a piecewise function (e.g. polynomial) 如何添加成员 function 作为例如 Boost Log 过滤器? - How do I add a member function as e.g. Boost Log filter? 必须使用'。*'或' - > *'在'lessThan(...)'中调用指向成员的函数,例如'(... - > * lessThan)(...)' - must use '.*' or '->*' to call pointer-to-member function in 'lessThan (…)', e.g. '(… ->* lessThan) (…)' 使用enable_if和SFINAE时函数参数类型推导(std容器,例如vector)失败 - function argument type deduction (std container e.g. vector) fails when using enable_if and SFINAE 文字类类型成员函数约束 - Literal class type member function constraints Libclang:在 SourceLocation 获取符号(例如函数) - Libclang: Get Symbol (e.g. function) at SourceLocation 使用 CGAL 的基本 function,例如 `square` - Using a basic function of CGAL, e.g. `square` 比较函数放在哪里(例如std :: sort)? - Where to put comparison function for use with (e.g.) std::sort?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM