2016-03-01 2 views
1

Что не так? Я хотел бы, чтобы строка xconcat работала.Препроцессор C++ ## operator

#define concat(a,b) a ## b 
#define xconcat(a,b) concat(a,b) 

int main() { 
    xconcat(xconcat(boost::variant<,int), >) y; 
    boost::variant<int> x; 
    return 0; 
} 

г ++ -E x.cpp

# 1 "x.cpp" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "x.cpp" 



int main() { 
x.cpp:5:1: error: pasting "<" and "int" does not give a valid preprocessing token 
x.cpp:5:1: error: pasting "int" and ">" does not give a valid preprocessing token 
    boost::variant<int > y; 
    boost::variant<int> x; 
    return 0; 
} 
+0

Примечание: недоставленный редактирование тега (1 правильный тег был удален и добавлено 3 неправильных тега) –

ответ

1

Маркер Оператор вставки технически не может быть использована, чтобы вставить что-то, что не в конечном итоге быть маркером. GCC применяет это ограничение, в то время как некоторые другие компиляторы не делают (оператор ## просто выполняет базовую конкатенацию строк, которые затем становятся токенированными позже).

От C++ 11 16.3.3/3 "О ## оператора":

Если результат не является допустимым маркер предварительной обработки, поведение не определено.

Этот же язык используется практически во всех стандартах C и C++, начиная с C90.

В вашем случае вам не нужно использовать маркер вставки, так как вы имеете дело с отдельными лексем все равно:

#define yyconcat(a,b) a b 
#define yconcat(a,b) yyconcat(a,b) 

int main() { 
    yconcat(yconcat(boost::variant<,int), >) y; 
    boost::variant<int> x; 
    return 0; 
} 

г ++ -E так test.c

C:\so-test>g++ -E so-test.c 
# 1 "so-test.c" 
# 1 "<command-line>" 
# 1 "so-test.c" 



int main() { 
    boost::variant<int> y; 
    boost::variant<int> x; 
    return 0; 
} 
+0

Что это за «многие компиляторы»? MSVC - это всего лишь один компилятор. – rici

+0

OK «много» может быть слишком сильным словом. К моему воспоминанию, GCC является единственным компилятором, которого я заметил, жалуются на это использование вставки маркера. Я использовал несколько компиляторов, кроме GCC и MSVC, но я думаю, что вы правы, что все еще не «много». Я думаю, что даже старые версии GCC (как и старые версии v2.95) не жаловались, но я мог вспомнить, что все не так. –

+1

'#define yconcat (a, b) a b' будет проще –

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