20

My internal sanity check failed so I'm rerunning it on Stackoverflow.

The following code:

#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");
}

produces the mangled symbol name for std::__1::pair<int, int> on my system (XCode Clang 8.x).

If I then enable the static_assert, it fails. I have no idea why. How can I make this work? I have a function that returns a pair or tuple depending on the arguments passed to it and would like to verify it actually returns a pair or tuple in the correct cases.

rubenvb
  • 74,642
  • 33
  • 187
  • 332

1 Answers1

37

You declared pair_of_ints as constexpr which implies const:

[dcl.constexpr]#9

A constexpr specifier used in an object declaration declares the object as const.

So the type of pair_of_ints is actually:

const std::pair<int, int>

typeid ignores cv-qualifiers, which is why this information does not appear in the name:

[expr.typeid]#5

If the type of the expression or type-id is a cv-qualified type, the result of the typeid expression refers to a std::type_info object representing the cv-unqualified type.

You could either test against the const-qualified type, or drop the const-qualifier using 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);
Holt
  • 36,600
  • 7
  • 92
  • 139
  • 2
    It is also possible to remove CV qualifiers in a type (since C++11) using [std::remove_cv](http://en.cppreference.com/w/cpp/types/remove_cv) – Jorge Bellon Jan 29 '18 at 11:17
  • @JorgeBellón -- just for completeness, it was possible to remove CV qualifiers from a type before C++11. It's a fairly straightforward use of templates. C++11 added those templates to the standard library, making them more readily accessible. – Pete Becker Jan 29 '18 at 14:06
  • @PeteBecker you are right. I actually messed with the wording by putting the reference to the standard before the link and not afterwards. – Jorge Bellon Jan 29 '18 at 14:32