Require Some Insight On Proper Fundamental Type Overloading

Hello there.

I am currently working with the fundamental types in C++, and there is some ambiguity (which I have tried to solve).

I am creating a function that needs an overload for _all_ fundamental types (in addition to a void *).
Some types overlap (like "unsigned wchar_t" and unsigned int, whilst wchar_t never overlaps), so, I would like some confirmation about my current overloads being complete and overlap-free on your system as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
bool

char
unsigned char
signed char

wchar_t
char16_t // In fact, builtin-types, look like typedef.
char32_t

short
unsigned short

int 
unsigned int

long int
unsigned long int

long long int
unsigned long long int

float
double
long double

void
void *
decltype(nullptr)



To test the valid types, I have created a small test that shows which builtin types overlap and which do not.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <typeinfo>


int main(int argc, char *argv[])
{
    std::map<std::size_t, std::vector<std::string>> m;

    m[typeid(bool).hash_code()].push_back("bool");

    m[typeid(char).hash_code()].push_back("char");
    m[typeid(unsigned char).hash_code()].push_back("unsigned char");
    m[typeid(signed char).hash_code()].push_back("signed char");

    m[typeid(wchar_t).hash_code()].push_back("wchar_t");
    m[typeid(unsigned wchar_t).hash_code()].push_back("unsigned wchar_t");
    m[typeid(signed wchar_t).hash_code()].push_back("signed wchar_t");

    m[typeid(short).hash_code()].push_back("short");
    m[typeid(unsigned short).hash_code()].push_back("unsigned short");
    m[typeid(signed short).hash_code()].push_back("signed short");

    m[typeid(int).hash_code()].push_back("int");
    m[typeid(unsigned int).hash_code()].push_back("unsigned int");
    m[typeid(signed int).hash_code()].push_back("signed int");

    m[typeid(long int).hash_code()].push_back("long int");
    m[typeid(unsigned long int).hash_code()].push_back("unsigned long int");
    m[typeid(signed long int).hash_code()].push_back("signed long int");

    m[typeid(long long int).hash_code()].push_back("long long int");
    m[typeid(unsigned long long int).hash_code()].push_back("unsigned long long int");
    m[typeid(signed long long int).hash_code()].push_back("signed long long int");

    m[typeid(float).hash_code()].push_back("float");
    m[typeid(double).hash_code()].push_back("double");
    m[typeid(long double).hash_code()].push_back("long double");

    m[typeid(char16_t).hash_code()].push_back("char16_t");
    m[typeid(char32_t).hash_code()].push_back("char32_t");

    m[typeid(void).hash_code()].push_back("void");
    m[typeid(decltype(nullptr)).hash_code()].push_back("decltype(nullptr)");
    m[typeid(nullptr).hash_code()].push_back("nullptr");
    m[typeid(void *).hash_code()].push_back("void *");


    for (auto &x : m)
    {
        if (x.second.size() > 1)
            std::cout << "TYPES OVERLAP\n";
        for (auto &y : x.second)
            std::cout << y << "\n";
        std::cout << "\n";
    }

}


I also wonder; what "type" is nullptr? I tried googling but no definitive answers came up.
Still, it works as a valid function overload.
I also wonder; what "type" is nullptr?
std::nullptr_t
I also wonder; what "type" is nullptr?

The type is called std::nullptr_t : http://en.cppreference.com/w/cpp/types/nullptr_t -- you need to #include <cstddef> to access its name.

The types you listed before the program are all distinct types as guaranteed by the standard.

Your program involves a few pairs of same types:
short and signed short, int and signed int, long and signed long, long long and signed long long are the same, by definition.

it also has two errors, to quote clang,

1
2
3
4
5
6
main.cpp:19:14: warning: 'wchar_t' cannot be signed or unsigned [-Wpedantic]
    m[typeid(unsigned wchar_t).hash_code()].push_back("unsigned wchar_t");
             ^
main.cpp:20:14: warning: 'wchar_t' cannot be signed or unsigned [-Wpedantic]
    m[typeid(signed wchar_t).hash_code()].push_back("signed wchar_t");
             ^


or, using somewhat less-clear gcc,

1
2
test.cc:19:23: warning: long, short, signed or unsigned used invalidly for 'type name' [-pedantic]
test.cc:20:21: warning: long, short, signed or unsigned used invalidly for 'type name' [-pedantic]


PS: don't forget that for any non-reference non-function type there are three more distinct versions: const, volatile, and const volatile.
Last edited on
@kbw

That is not helping a lot tho,..

1
2
3
4
5
6
#if defined(__cplusplus) && __cplusplus >= 201103L
#ifndef _GXX_NULLPTR_T
#define _GXX_NULLPTR_T
  typedef decltype(nullptr) nullptr_t;
#endif
#endif /* C++11.  */ 


I read that it's a builtin type; but I have no idea how to read it or how to change an instantiation of it.

@Cubbi
I am aware that signed can be omitted. Also, it's quite weird that you get errors with signed and unsigned wchar_t types. TDM-GCC 4.8.1 has no problem at all. I'll check the C++ documentation.


Edit:

-pedantic-errors causes an error just like with you, I will omit these from code.
Last edited on
Topic archived. No new replies allowed.