На самом деле я только что нашел ответ на мой собственный вопрос:
template<typename T>
void show_type_abort_helper()
{
return __PRETTY_FUNCTION__;
}
#define show_type_abort(x) show_type_abort_helper< decltype(x) >()
Использование:
std::vector<int> s{1, 2, 3};
for (auto elem : s) {
show_type_abort(elem);
elem = 5;
}
Производит следующее сообщение об ошибке с g++
(версия 6.1.1):
$ g++ test.cpp
test.cpp: In instantiation of ‘void show_type_abort_helper() [with T = int]’:
^^^
test.cpp:17:9: required from here
test.cpp:7:12: error: return-statement with a value, in function returning 'void' [-fpermissive]
return __PRETTY_FUNCTION__;
Проверьте вывод на T = int
, чтобы увидеть, как компилятор использует int
как type. Это похоже на работу с лязгом, а также:
$ clang++-3.8 -std=c++11 test.cpp
test.cpp:7:5: error: void function 'show_type_abort_helper' should not return a value [-Wreturn-type]
return __PRETTY_FUNCTION__;
^ ~~~~~~~~~~~~~~~~~~~
test.cpp:17:9: note: in instantiation of function template specialization 'show_type_abort_helper<int>' requested here
^^^
show_type_abort(elem);
Изменение в for (const auto& elem : s)
дает
with T = const int&
^^^^^^^^^^
или
show_type_abort_helper<const int &>
^^^^^^^^^^^
Так, кажется, я могу узнать тип во время компиляции и отмены. Это очень пригодилось для очень сложного типа, состоящего из нескольких параметров typedef и шаблонов, где я просто не мог видеть, что происходит.
Не знаете, что вы просите. Любой код, который вы напишете, чтобы убедиться, что «elem» является ссылкой, кажется немного дольше, чем для начала написания «auto && elem». – Barry
Вы можете использовать ['std :: is_reference'] (http://en.cppreference.com/w/cpp/types/is_reference) вместе с [' static_assert'] (http://en.cppreference.com/w/CPP/язык/static_assert). Но он добавляет, что для каждого цикла больше работы, чем просто для того, чтобы начать использовать правильный тип.И нет, нет способа заставить компилятор сделать чек для вас, поскольку назначение не является каким-либо недопустимым. –
Ваш пример выглядит повод для предупреждения компилятора. Например, мой компилятор говорит «предупреждение: переменная« elem »установлена, но не используется'. – Sergey