почему auto нельзя использовать для перегрузки функций?

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

N3690 говорит в 7.6.1.4/3, что лямбда-выражение можно сделать универсальным, используя auto, предоставляя этот пример

auto glambda = [](int i, auto a) { return i; };//OK: a generic lambda

(примечание: это не упоминается в N3485)

1). Почему я не могу сделать то же самое для нормальной функции, например,

void swap(auto& param1, decltype(param1)& param2)
{
decltype(param1) temp = param1;
param1 = param2;
param2 = temp;
}

это дает ошибки error : parameters declared auto,

от N3690 7.1.6.4/4

Тип переменной, объявленной с использованием auto или decltype (auto), выводится из ее
инициализатор. Это использование разрешено при объявлении переменных в блоке (6.3), в области имен (3.3.6) и в for-init-утверждении (6.5.3). […]

я ошибаюсь, предполагая, что param1 а также param2 подпадают под область блока и, следовательно, имеют право на автоматическое удержание?

2). Если бы такая возможность была разрешена, какие бы были подводные камни?

Я использую GCC 4.8.1.

Спасибо

15

Решение

n3690 7.1.6.4/2


Тип заполнителя может появиться с помощью объявления функции в decl-specier-seq, type-specier-seq,
Conversion-Function-ID, или Trailing-Return-Type, в любом контексте, где такой декларатор является действительным.


7.1.6.4/3


Если автоматический спецификатор типа появляется как один из спецификаторов decl в decl-specier-seq параметра-
объявление лямбда-выражения, лямбда — это общее лямбда.


7.1.6.4/4


Тип переменной, объявленной с использованием auto или decltype (auto), выводится из ее инициализатора. Это использование
понижается при объявлении переменных в блоке (6.3), в области пространства имен (3.3.6) и в for-init-Statement (6.5.3).
auto или decltype (auto) должны появиться как один из спецификаторов decl в decl-specier-seq и в decl-
за параметром-seq должен следовать один или несколько init-объявлений, каждый из которых должен иметь непустую начальную
Izer.


7.1.6.4/5

Тип заполнителя также можно использовать при объявлении переменной в условии оператора выбора (6.4) или
оператор итерации (6.5) в спецификаторе типа-seq в new-type-id или type-id нового выражения (5.3.4), в
объявление для диапазона и в объявлении статического члена данных с инициализатором скобки или равным, который появляется
в спецификации члена определения класса (9.4.2).


Допускается только такое использование. Любое другое использование запрещено (в частности, использование в parameter-declaration-clause).

7.1.6.4/6


Программа, которая использует auto или decltype (auto) в контексте, явно не разрешенном в этом разделе, неверна.

5

Другие решения

N3690 — это проект комитета для C ++ 14, то есть для следующего стандарта C ++, который еще не выпущен и который еще не может быть реализован в большинстве компиляторов. Так что вам следует обратиться к документации вашего компилятора, если реализованы общие лямбды — я думаю, что это не так.

Однако, с gcc у вас есть хорошие шансы, что функции C ++ 14 будут реализованы до официального выпуска нового стандарта, хотя вам, возможно, придется явно включить поддержку C ++ 14 с флагом командной строки. Глядя на документы, это должно быть -std=gnu++1y

В соответствии с этот сайт, общие лямбды еще не реализованы в GCC.

Обновить:
Что касается обычных универсальных функций, использующих auto параметры: они не существуют и не будут приходить в следующий раз. Причина в том, что шаблонные функции являются лишь немного более многословными по типу и более мощными, поскольку вы можете ссылаться на типы и напрямую применять к ним метафункции шаблонов. В общих лямбдах это можно сделать только с помощью decltype(a), который немного более утомителен и должен использоваться с осторожностью, потому что он ведет себя немного иначе, чем вывод аргумента шаблона.
Дополнительный бонус с шаблонами по сравнению с автоматическими параметрами — немного больше безопасности типов или выразительности:

void func(auto a, auto b);  //a and b might be different types

template <class T>
void func(T a, T b); //a and b must be the same type
2

На вершине навсегда«s ответ:

Почему я не могу сделать то же самое для нормальной функции, например,

void swap(auto& param1, decltype(param1)& param2)

Просто потому, что язык не позволяет этого. До auto был (пере) изобретен в C ++ 11, что вы хотели бы достичь с помощью шаблонов:

template <class T, class U>
void swap(T& param1, U& param2);

C ++ 11 также использует лямбда-выражения, а C ++ 14, вероятно, вводит полиморфные лямбды, которые, в основном, являются лямбдами, чьи operator () шаблоны. Синтаксис, подобный шаблонам, был рассмотрен, например, для полиморфных лямбд (пример взят из N3418)

[]<class T>(T* p) { /* ... */ }

В конце концов, предпочтительный синтаксис использовал auto вместо того, чтобы вводить список параметров шаблона.

Это правда, что можно рассмотреть возможность расширения этого более короткого синтаксиса для шаблонов функций (как предполагает OP), но, насколько я знаю, комитет не рассматривал эту возможность. Это может произойти в будущем, но кто-то должен официально предложить это. Это может быть «приятной особенностью», но имхо, это просто синтаксический сахар, который мало что дает языку.

Кроме того, я не вижу, как этот краткий синтаксис (без списков параметров шаблона) можно использовать для шаблонных классов, и, возможно, отличать синтаксис для шаблонных функций от синтаксиса шаблонных классов не стоит.

1

Уже есть способ написать то, что вы хотели:

template <class T>
void swap(T& param1, T& param2)
{
T temp = param1;
param1 = param2;
param2 = temp;
}

Так зачем создавать новый синтаксис, который не позволяет вам делать то, что вы не могли сделать раньше. Предлагаемое изменение лямбда-выражений состоит в том, чтобы разрешить общие лямбда-выражения, которые вы не могли сделать раньше, и я предполагаю, что любой синтаксис, использующий синтаксис шаблона, был бы здесь безобразным.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector