При просмотре некоторого кода на работе я заметил кое-что, что, по моему мнению, не должно компилироваться, но, к моему удивлению, так и происходит.
В заголовочном файле определена функция шаблона:
template <class T>
web::json::value get_key(const web::json::value &json, const utility::string_t &key) {
return json.has_field(key) ? json.at(key) : web::json::value(T());
}
со специализацией в исходном файле:
template <>
web::json::value get_key<utility::string_t>(const web::json::value &json, const utility::string_t &key) {
return json.has_string_field(key) ? json.at(key) : web::json::value(utility::string_t());
}
Редактировать: Специализация не объявлена в заголовочном файле.
Насколько я могу судить, это должно привести ккомпилятор выдает два различных определения для get_key<utility::string_t>
, одно для специализации в исходном файле и одно всякий раз, когда создается первичный шаблон, что нарушает ODR.Однако g ++ 8.3.1 компилирует и связывает это без каких-либо ошибок.
Может кто-нибудь объяснить мне, что здесь происходит?Я что-то упустил, и приведенный выше код действительно действителен, или это просто некое неопределенное поведение?
Спасибо!