Comments 10
auto lmbd = [](auto i){...}; // Сейчас - нет, но в С++14 - да
Напомнило:
In C++14 you just write «auto auto(auto auto) { auto; }»
. The compiler infers the rest from context.
Вобще, auto для простых типов хорошо подходит, но когда сложносоставные, то можно получить такую вот штуку
auto smth = new Heavy_class<Some_class<Foo_bar>,int>();
//....
delete smth; // error: smth is not pointer
> Очевидно, тут дело в том, что если бы такое было разрешено, то, получается, любую обычную функцию можно было бы объявить по сути неявно шаблонной. И становится непонятно как разрешать перегрузку.
Очень даже понятно — именно так и разрешать, раскрыв auto в шаблонную функцию, а потом по обычным правилам. Т.е. ваш пример:
Раскрывается в:
Что, разумеется, приводит к неопределнности при вызове с любыми параметрами — по уже существующим правилам.
Просто реальная область применения у подобного для функций небольшая. Вот для лямбд это было интересно, потому для них его и сделали.
Очень даже понятно — именно так и разрешать, раскрыв auto в шаблонную функцию, а потом по обычным правилам. Т.е. ваш пример:
auto foo(auto v1, auto v2) -> decltype(v1+v2) ;
int foo(auto v1, bool v2);
Раскрывается в:
template<class V1, class V2>
auto foo(V1 v1, V2 v2) -> decltype(v1+v2) ;
template<class V1, class V2>
int foo(V1 v1, V2 v2);
Что, разумеется, приводит к неопределнности при вызове с любыми параметрами — по уже существующим правилам.
Просто реальная область применения у подобного для функций небольшая. Вот для лямбд это было интересно, потому для них его и сделали.
Что, разумеется, приводит к неопределнности при вызове с любыми параметрами — по уже существующим правилам.
Ваша версия кода — да, но, по-моему, «раскрытие» было выполнено неверно, должно быть:
template<class V1, class V2>
auto foo(V1 v1, V2 v2) -> decltype(v1+v2);
template<class V1>
int foo(V1 v1, bool v2);
А это уже вполне себе компилируется.
P.S. Это я не к тому, кто прав, а кто нет. Просто указать на неточность.
Крайне неинтуитивные конструкции.
Хотел бы рассказать еще один секрет про auto и decltype, но неохото создавать новую тему ибо она слишком мала.
А секрет заключается в следующем:
обращение к параметру this в статическом методе
А секрет заключается в следующем:
обращение к параметру this в статическом методе
class Foo {
static auto self() -> decltype(this);
};
А это точно секрет, а не особенность реализации некоторых компиляторов? В стандарте оговорено что-нибудь об этом?
Но ведь…
… пишется быстрее, гораздо очевиднее и не содержит подводных камней.
using self = Foo;
… пишется быстрее, гораздо очевиднее и не содержит подводных камней.
Во первых это был способ, а не цель.
Цель заключается в том, чтобы получить собственный тип не зная своего имени класса.
using self = Foo; — это конечно очевидно, но появляется возможность ошибки, например копипаста.
Можно сделать такой define:
а потом применять его где это необходимо:
Ну а для чего нужен собственный тип? например для следующего:
Цель заключается в том, чтобы получить собственный тип не зная своего имени класса.
using self = Foo; — это конечно очевидно, но появляется возможность ошибки, например копипаста.
Можно сделать такой define:
#define DECLARE_SELF \
static auto selfTypeHelper() -> UnPtr<decltype(this)>; \
using Self = decltype(selfTypeHelper())
а потом применять его где это необходимо:
class Foo {
DECLARE_SELF;
};
Ну а для чего нужен собственный тип? например для следующего:
...
offsetof(Self, field);
...
Sign up to leave a comment.
Секреты auto и decltype