2015-02-22 6 views
0

Я пытаюсь очистить унаследованную базу кода. Он широко использует функции шаблонов, которые включают в себя тип возвращаемого возврата. Он также включает в себя множество указателей на функции, не связанные с шаблоном, не входящие в функции. Во время очистки я обнаружил, что код, эквивалентный следующие работы под Visual Studio 2013:C++ 11 указатель функции typedef с возвращаемым типом возврата

#define function typedef auto 

function Kernel (int, int) -> int; 

struct Transform 
{ 
    Kernel* kernel; 
    char* description; 
}; 

Transform add_transform { add, "add" }; 

Является ли это ЬурейеЕ действует в стандарте C++ 11?

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

+2

'typedef auto Kernel (int, int) -> int;' является законным. Тем не менее, попробуйте использовать 'std :: function' с этим макросом. –

+0

Я не мог согласиться больше - к сожалению, моя команда не согласна! Я надеялся, что он будет зависимым от компилятора, чтобы я мог отговорить их от его использования. –

+0

'using Kernel = int (int, int);' более читаемый и фактически действительный синтаксис C++. – Casey

ответ

4

Синтаксис возвращаемого типа возврата является новым в C++ 11, и он действителен везде, где вы можете написать тип функции. auto <function>(<parameters>) -> <result> - это просто причудливый способ написания <result> <function>(<parameters>) (с учетом того, что <result> может ссылаться на <parameters>).

Это означает, что typedef auto Kernel (int, int) -> int; совершенно справедливо и означает точно такую ​​же вещь, как typedef int Kernel (int, int);. То, что typedef может быть использовано в объявлениях функций или указателей на функции.

+0

Благодарим за подтверждение, что это законно в C++ 11. Мне на самом деле очень нравится форма typedef auto ..., поскольку она обращается к моей математике. Тем не менее, я ненавижу #define, и я надеялся, что этого не будет. –

3

Может возникнуть соблазн заново создать синтаксис C++ с использованием макросов. Вы могли бы придумать что-то классное и подумать «вау, это намного более ясно».

Самая фундаментальная проблема с этим подходом заключается в том, что он более читабельен для парня, изобретающего макрос, или если вы не знаете C++ достаточно хорошо. Если вы прекрасно понимаете, что означает typedef auto fn(int) -> int, то вы больше не найдете свой макрос вообще. Синтаксис уже достаточно ясен.

Для создания сложных вещей вы представляете все множество проблем с помощью макросов. Вы захватываете имя символа function по всем направлениям - независимо от объема. Теперь вы больше не можете использовать std::function. Вы можете не только не использовать его, но и собирать некоторые неприятные ошибки компилятора, которые не являются описательными вообще. Компилятор будет пытаться разобрать std::typedef auto, что является бессмыслицей.

+0

Моя благодарность - я направлю их на это сообщение завтра. –

1

Это действительно так, поскольку auto(int, int) -> int; является декларатором функции, за исключением того, что у него отсутствует имя. Имя, Kernel, является идентификатором, используемым спецификатором typedef для создания с типом. Поскольку присутствует тип возвратно-поступательного типа, auto заменяется на int, и он становится int(int, int). Если вы хотите, чтобы убедить свою команду, что это бесполезно, рассмотреть пути вы можете достичь того же синтаксиса:

using Kernel = int(int, int); 
using Kernel = auto(int, int) -> int; 
typedef auto Kernel(int, int) -> int; 

Это все семантически эквивалентны, и избегает использования макроса.

Смежные вопросы