Определение альтернативного члена С++

В С++ вы можете определить членов следующим образом:

struct test {
    using memberType = int(int);
    /*virtual*/ memberType member;
};

int test::member(int x) { return x; }

С С++ 14 есть ли способ определить член внутри определения класса, например, с помощью лямбда?

Ответы

Ответ 1

Я не думаю, что это возможно, но вы можете сделать это, если элемент является указателем на функцию

struct test {
    int (*member)(int) = [](int x){return x;};
};

поскольку лямбда с пустым списком захвата на самом деле является регулярной функцией

Ответ 2

Единственный способ, которым я мог думать о том, что мы должны использовать объект std::function<>, но вам нужно передать экземпляр (не можете придумать, как его можно автоматически связать..)

struct foo {
    using T = int(foo&, int);

    int b;
    std::function<T> x = [](foo& f, int a) { return a * f.b; };
};

Ответ 3

вы хотите написать что-то вроде этого:

struct test {
  auto member_impl = [this]() {
  };
};

Это не работает (по крайней мере) три счета:

  • Вы не можете объявить нестатический член auto.

  • Вы не можете назвать тип лямбда (поэтому он должен быть автоматически)

  • this недоступен во время определения класса.

Короткий ответ, нет.

но вы можете написать:

struct test {
  auto member_impl() {
  };
};

который примерно такой же короткий, как и он.

Ответ 4

Я думаю, 5.1.5/3 - это то, что мешает вам использовать лямбда так, как вы ее использовали, извините:

[...] Лямбда-выражение не должно появляться в неопубликованном операнде (раздел [expr]) в аргументе шаблона в объявлении alias в объявлении typedef или в объявлении функции или шаблон функции вне его тела функции и аргументы по умолчанию. [Примечание. Цель состоит в том, чтобы предотвратить появление лямбда в подписи. - конец примечания] [...]

Тем не менее, С++ 14 позволяет вам определять тип члена с использованием шаблонов, как в следующем примере:

template<typename F>
struct S;

template<typename R, typename... Args>
struct S<R(Args...)> {
    using member = R(Args...);
    R operator()(Args...) { return R{}; }
    member M;
};

template<typename R, typename... Args>
R S<R(Args...)>::M(Args...) { return R{}; }

int main() { S<void(int)> s; }