Почему std :: make_pair не возвращает пару? Или это?

Моя внутренняя проверка работоспособности не удалась, поэтому я переигрываю ее на Stackoverflow.

Следующий код:

#include <iostream>
#include <typeinfo>
#include <utility>

int main()
{
    constexpr auto pair_of_ints = std::make_pair(1, 2);
    std::cerr << typeid(pair_of_ints).name();
    //static_assert(std::is_same<decltype(pair_of_ints), std::pair<int, int>>::value, "WTF");
}

производит имя искаженного символа для std::__1::pair<int, int> в моей системе (XCode Clang 8.x).

Если я затем static_assert, он не сработает. Понятия не имею почему. Как я могу сделать эту работу? У меня есть функция, которая возвращает пару или кортеж в зависимости от переданных ему аргументов и хочет проверить, действительно ли она возвращает пару или кортеж в правильных случаях.

Ответ 1

Вы объявили pair_of_ints как constexpr что означает const:

[dcl.constexpr] # 9

constexpr используемый в объявлении объекта, объявляет объект как const.

Таким образом, тип pair_of_ints на самом деле:

const std::pair<int, int>

typeid игнорирует cv-квалификаторы, поэтому эта информация не появляется в имени:

[expr.typeid] # 5

Если тип выражения или идентификатор типа является cv-квалифицированным типом, результат выражения typeid относится к объекту std::type_info представляющему cv-unqualified type.

Вы можете либо протестировать тип const- qual, либо отказаться от конструктора- константы, используя std :: remove_const_t:

static_assert(std::is_same<decltype(pair_of_ints), 
                           const std::pair<int, int>>::value);
static_assert(std::is_same<std::remove_const_t<decltype(pair_of_ints)>, 
                           std::pair<int, int>>::value);