Определение альтернативного члена С++
В С++ вы можете определить членов следующим образом:
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; }