Я просто изменив старый пример моего кода путем добавления значного сепаратора к определенному пользователю буквальным, анализируются с помощью VARIADIC шаблона:Как пользовательские литералы играют вместе с разделителем цифр?
namespace lits {
// helper for 1 arg
template<char C> int bin(); // common
template<> int bin<'1'>() { return 1; } // spec.
template<> int bin<'0'>() { return 0; } // spec.
// helper 2 or more args
template<char C, char D, char... ES>
int bin() {
return bin<C>() << (sizeof...(ES)+1) | bin<D,ES...>() ;
}
// operator"" _bin
template<char...CS> int operator"" _bin()
{ return bin<CS...>(); };
}
int main() {
using namespace lits;
int number = 1000'0000_bin; // <<< I added a ' here
}
Мальчика, я был удивлен, когда на г ++ 6.2.0 пытался создать экземпляр bin<'\''>
. Он пытался передать '
как char
в мой шаблон template<char...CS> int operator"" _bin()
! Я попробовал это с clang ++ - 3.9 и msvC++ - 19.00, та же жалоба, которая действительно меня скептически.
У меня такое ощущение, что это может быть неправильное поведение. Я бы это понял, если бы мой литерал был в кавычках, скажем "1000'0000"_bin
, но эта форма не существует для оператора шаблона «», правильно?
Я должен ожидать разделителя цифр '
в моем шаблоне пользовательских литералов, тоже, теперь?
Update 1: в случае '
нормально:
Можно использовать цифры-SEP как ПОШ все рода вещи, скажем, комплексных числа. Было бы хорошо определено поведение `52.84'67.12_i 'для 52.84 + 67.12i?'
Udpdate 2: Как реакция некоторые из комментариев. Следующие компилирует:
#include <iostream>
#include <string>
using std::string;
namespace lits {
// helper
template<char C> string sx() { return string{}+C; }
// helper 2 or more args
template<char C, char D, char... ES>
string sx() {
return sx<C>() + sx<D,ES...>();
}
// operator"" _sx
template<char...CS> string operator"" _sx()
{ return sx<CS...>(); };
}
int main() {
using namespace lits;
std::cout << 10000000_sx << '\n';
std::cout << 10'000'000_sx << '\n';
std::cout << 0x00af_sx << '\n';
std::cout << 0x0'c'0'a'f_sx << '\n';
std::cout << 007_sx << '\n';
std::cout << 0b01_sx << '\n';
// the following do not work:
//std::cout << 0b0a8sh3s1_sx << '\n';
//std::cout << "abcde"_sx << '\n';
}
И выход:
10000000
10'000'000
0x00af
0x0'c'0'a'f
007
0b01
Это означает, что шаблон получает все символы: префиксы и цифры Сепараторы - все из них. (g ++ - 6.2.0)
Как следует из ответа @ krzaq, это, по-видимому, план Std, поэтому на него можно положиться.
Рассмотрите, как '01' и' 1' означают то же самое, что интерпретируются как 'int', но вы можете хотеть, чтобы' 01_bin' и '1_bin' интерпретировались по-разному (битовая строка длиной 2 по сравнению с битовой строкой длина 1). Независимо от того, что говорит стандарт (об этом уже сказано), имеет смысл, что вы получаете точное написание, которое пользователь использовал. Это зависит от вас, чтобы решить, какие отличия имеют значение, а какие нет. – hvd