На первый взгляд, это простой синтаксический сахар.
Но если взглянуть глубже, мы увидим, что это больше, чем синтаксический сахар, так как расширяет возможности пользователя C ++ для создания пользовательских типов, которые ведут себя точно так же, как отдельные встроенные типы. В этом, этом маленьком «бонус» - очень интересное дополнение C ++ 11 к C ++.
Нам действительно нужно это в C ++?
Я вижу несколько применений в коде, который я написал в последние годы, но только то, что я не использовал его в C ++, не означает, что он не интересен для другого разработчика C ++ .
Мы использовали в C ++ (и в C, я думаю) литералы, определенные компилятором, для ввода целых чисел в виде коротких или длинных целых, действительных чисел в виде числа с плавающей или двойной (или даже длинной двойной) и строк символов как обычно или широкие буквы.
В C ++ у нас была возможность создавать наши собственные типы (т.е. классы), потенциально без накладных расходов (вставка и т. Д.). У нас была возможность добавлять операторы к их типам, чтобы они вели себя как похожие встроенные типы, что позволяет разработчикам на C ++ использовать матрицы и комплексные числа так же естественно, как если бы они были добавлены в сам язык. Мы даже можем добавить операторы приведения (что обычно является плохой идеей, но иногда это просто правильное решение).
Мы все еще упустили одну вещь, чтобы пользовательские типы вели себя как встроенные типы: пользовательские литералы.
Итак, я полагаю, что это естественная эволюция языка, но она должна быть настолько полной, насколько это возможно: " Если вы хотите создать тип и хотите, чтобы он вел себя настолько, насколько это возможно, как встроенные типы вот инструменты ..."
Полагаю, это очень похоже на решение .NET сделать каждый примитив структурой, включая логические, целые и т. Д., И иметь все структуры, производные от Object. Одно только это решение делает .NET гораздо более недоступным для Java при работе с примитивами, независимо от того, сколько хаков для бокса / распаковки Java добавит к своей спецификации.
Тебе действительно нужно это в C ++?
Этот вопрос для ВЫ , чтобы ответить. Не Бьярне Страуструп. Не Херб Саттер. Не то, что член стандартного комитета C ++. Вот почему у вас есть выбор в C ++ , и они не будут ограничивать полезную запись только встроенными типами.
Если вам это нужно, то это долгожданное дополнение. Если вы нет, ну ... не используйте его. Это вам ничего не будет стоить.
Добро пожаловать в C ++, язык, где функции являются необязательными.
Раздутое ??? Покажи мне свои комплексы !!!
Существует различие между раздутым и сложным (каламбур).
Как показано Niels на Какие новые возможности пользовательские литералы добавляют в C ++? , возможность записать комплексное число является одной из двух функций, недавно добавленных в C и C ++:
// C89:
MyComplex z1 = { 1, 2 } ;
// C99: You'll note I is a macro, which can lead
// to very interesting situations...
double complex z1 = 1 + 2*I;
// C++:
std::complex<double> z1(1, 2) ;
// C++11: You'll note that "i" won't ever bother
// you elsewhere
std::complex<double> z1 = 1 + 2_i ;
Теперь и тип C99 «двойной комплекс», и тип C ++ «std :: complex» можно умножать, добавлять, вычитать и т. Д., Используя перегрузку операторов.
Но в C99 они просто добавили еще один тип как встроенный тип и встроенную поддержку перегрузки операторов. И они добавили еще одну встроенную буквальную функцию.
В C ++ они просто использовали существующие возможности языка, увидели, что буквальная особенность является естественной эволюцией языка, и таким образом добавили его.
В C, если вам нужно такое же улучшение обозначений для другого типа, вам не повезло, пока вы не лоббировали добавить свои квантовые волновые функции (или 3D-точки, или любой другой базовый тип, который вы используете в своей области работы ) к стандарту C как встроенный тип успешно.
В C ++ 11 вы просто можете сделать это самостоятельно:
Point p = 25_x + 13_y + 3_z ; // 3D point
Это раздутый? Нет , необходимость есть, как показывает то, как комплексы C и C ++ нуждаются в способе представления своих буквальных комплексных значений.
Это неправильно спроектировано? Нет , он разработан как любая другая функция C ++ с учетом расширяемости.
Это только для обозначения? Нет , поскольку это может даже добавить безопасность типов в ваш код.
Например, давайте представим CSS-ориентированный код:
css::Font::Size p0 = 12_pt ; // Ok
css::Font::Size p1 = 50_percent ; // Ok
css::Font::Size p2 = 15_px ; // Ok
css::Font::Size p3 = 10_em ; // Ok
css::Font::Size p4 = 15 ; // ERROR : Won't compile !
Тогда очень легко применить строгую типизацию к присвоению значений.
Опасно?
Хороший вопрос. Могут ли эти функции быть пространством имен? Если да, то джекпот!
В любом случае, как и все, вы можете убить себя, если инструмент используется ненадлежащим образом . C мощный, и вы можете отстрелить голову, если вы неправильно используете пистолет C. В C ++ есть пистолет C, а также скальпель, тазер и любой другой инструмент, который вы найдете в наборе инструментов. Вы можете неправильно использовать скальпель и истечь кровью до смерти. Или вы можете создать очень элегантный и надежный код.
Итак, как и любая функция C ++, она вам действительно нужна? Это вопрос, на который вы должны ответить, прежде чем использовать его в C ++. Если вы этого не сделаете, это ничего не будет вам стоить. Но если вам это действительно нужно, по крайней мере, язык не подведет.
Пример даты?
Мне кажется, ваша ошибка в том, что вы смешиваете операторы:
1974/01/06AD
^ ^ ^
Этого нельзя избежать, потому что / будучи оператором, компилятор должен его интерпретировать. И, AFAIK, это хорошо.
Чтобы найти решение вашей проблемы, я бы написал литерал другим способом. Например:
"1974-01-06"_AD ; // ISO-like notation
"06/01/1974"_AD ; // french-date-like notation
"jan 06 1974"_AD ; // US-date-like notation
19740106_AD ; // integer-date-like notation
Лично я бы выбрал целое число и даты ISO, но это зависит от ВАШИХ потребностей. В этом и заключается смысл позволить пользователю определять свои собственные литеральные имена.