Могут ли пользовательские литералы иметь функции в качестве аргументов? - PullRequest
4 голосов
/ 12 ноября 2011

Можно ли использовать функции с пользовательскими литералами?

Если это так, какие махинации можно выполнить?Это законно?

void operator "" _bar(int (*func)(int)) {
  func(1);
}

int foo(int x) {
  std::cout << x << std::endl;
}

int main() {
  foo(0);    // print 0
  foo_bar;   // print 1
}

Ответы [ 4 ]

7 голосов
/ 12 ноября 2011

Согласно проекту C ++ от 11 февраля 2011 г. § 2.14.8, пользовательские литеральные типы - это целочисленные литералы, плавающие литералы, строковые литералы и символьные литералы. Нет способа сделать функционально-литеральный тип.

Пользовательский литерал обрабатывается как вызов литерального оператора или шаблон буквального оператора (13.5.8). Чтобы определить форму этого звонка для заданного пользователем литерала L с UD-суффиксом X, ищется литеральный идентификатор оператора, чей буквенный идентификатор суффикса X в контексте L, используя правила для поиска безоговорочного имени (3.4.1). Пусть S будет набором объявлений, найденных этим поиском. S не должно быть пустым.

Целые числа:

operator "" X (n ULL)
operator "" X ("n")
operator "" X <’c1’, ’c2’, ... ’ck’>()

Плавающий:

operator "" X (f L)
operator "" X ("f")
operator "" X <’c1’, ’c2’, ... ’ck’>()

Строка:

operator "" X (str, len)
operator "" X <’c1’, ’c2’, ... ’ck’>() //unoffcial, a rumored GCC extension

Характер:

operator "" X (ch)
1 голос
/ 15 января 2012

Я не знаю, добавляет ли это что-нибудь, но ничто не мешает вам определить

PythonScript operator"" _python(const char*, std::size_t len) {...}

R"Py(
  print "Hello, World"
)Py"_python;

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

1 голос
/ 12 ноября 2011

номер

C ++ намеренно избегает таких махинаций, так как символ foo_bar будет очень трудно понять, если он не был определен непосредственно перед его использованием в вашем примере.

С препроцессором можно добиться чего-то похожего.

#define bar (1)

int foo(int x) {
  std::cout << x << std::endl;
}

int main() {
  foo(0);    // print 0
  foo bar;   // print 1
}
1 голос
/ 12 ноября 2011

Посмотрите на foo_bar, это всего лишь один лексический токен.Он интерпретируется как отдельный идентификатор с именем foo_bar, а не как foo с суффиксом _bar.

...