19

I referred to http://en.cppreference.com/w/cpp/language/typeid to write code which does different things for different types.

The code is as below and the explanation is given in the comments.

#include <iostream>
#include <typeinfo>

using namespace std;

template <typename T>
void test_template(const T &t)
{
    if (typeid(t) == typeid(double))
        cout <<"double\n";
    if (typeid(t) == typeid(string))
        cout <<"string\n";
    if (typeid(t) == typeid(int))
        cout <<"int\n";
}

int main()
{
    auto a = -1;
    string str = "ok";
    test_template(a); // Prints int
    test_template("Helloworld"); // Does not print string
    test_template(str); // Prints string
    test_template(10.00); // Prints double

    return 0;
}

Why does test_template(str) print "string" whereas test_template("Helloworld") does not?

BTW, my g++ version is g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Meehatpa
  • 349
  • 2
  • 10
  • 18
    Why the downvotes? Sure, it's at a basic level, but the question is complete, clear, and OP even includes a compiler version! – TartanLlama Jan 09 '17 at 14:18
  • 3
    `"Helloworld"` is not a `std::string`. But `"Helloworld"s` would be. – Jarod42 Jan 09 '17 at 15:07
  • 2
    @TartanLlama: I would guess it's because of a user wanting to use `typeid` to write horribly fragile code. – Nicol Bolas Jan 09 '17 at 21:33
  • Yeah, that's not a thing that site advises. `typeid` is handy for debugging/testing assumptions of complex, template code in my experience; & presumably some non-debugging polymorphic situation that I've thankfully never needed. If you don't need the latter, it's not a replacement for overloading. One of these is fully standard & predictable; the other is a brittle implementation-defined mapping of types to usually unhelpful codes. Using templates with `typeid` will produce _at best_ code that is no more efficient, but much less bearable to read, than using normal functions & overloading them. – underscore_d Jan 10 '17 at 01:54
  • ...and if, after all that, you do find yourself needing to branch based on the `typeid` of a polymorphic object at runtime, then I _think_ the accepted wisdom is that it probably indicates a flaw in the design. – underscore_d Jan 10 '17 at 02:00
  • @TartanLlama Downvoting isn't going to teach anybody how to program better. Well written answers, on the other hand, will :) – Jordan Melo Jan 13 '17 at 17:10

3 Answers3

21

In this call

test_template("Helloworld"); // Does not print string

the argument "Helloworld" is a string literal that has type const char[11].

Because the function parameter is a referenced type

void test_template(const T &t) 
                          ^^^

then within the function the argument (more precisely the parameter) has the type const char ( &t )[11].

String literals in C++ have types of constant character arrays with the number of elements equal to the number of characters in string literal plus the terminating zero.

In this call

test_template(str); 

the argument has type std::string because the variable str is declared like

string str = "ok";
^^^^^^

It was initialized by the string literal "ok" nevertheless the object itself is of the type std::string.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
16

String literals in C++ are of type const char[N+1], where N is the number of characters in the string. std::string is a standard library class which owns a string and provides a number of operations over it. A std::string can be constructed from a const char[N], but they are not the same thing.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
10

String literals like "Helloworld" are constants arrays of characters.

The std::string class have a constructor that can take pointers to string literals, but a string literal is in itself not a std::string object.


As a side-note, using a function like your is considered a code-smell and bad design. Use overloaded functions taking different arguments instead. That will also solve your problem with the strings.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621