2016-06-14 5 views
15

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

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

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

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

+2

Что польза от типа псевдоним? Вы уже обнаружили, что это умаляет вашу способность определять члена внутри класса. – chris

+0

@chris, может быть, он хочет использовать его как тип для 'std :: function'? –

+2

Я просто изучаю темные углы стандарта C++, чтобы найти новые способы написания более общего кода. – Gaetano

ответ

7

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

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

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

+4

И вы также можете сохранить свой псевдоним, если вы измените его на 'using memberType = int (*) (int);' – Smeeheey

1

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

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

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

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

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

Это не будет работать на (по крайней мере) три пунктов:

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

  2. Вы не можете назвать тип лямбда (поэтому он должен быть авто)

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

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

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

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

, который столь же коротким, как он получает.

1

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

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

Тем не менее, C++ 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; } 
Смежные вопросы