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.

6
  • 18
    Why the downvotes? Sure, it's at a basic level, but the question is complete, clear, and OP even includes a compiler version! Commented Jan 9, 2017 at 14:18
  • 3
    "Helloworld" is not a std::string. But "Helloworld"s would be. Commented Jan 9, 2017 at 15:07
  • 2
    @TartanLlama: I would guess it's because of a user wanting to use typeid to write horribly fragile code. Commented Jan 9, 2017 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. Commented Jan 10, 2017 at 1: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. Commented Jan 10, 2017 at 2:00

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Should conat char be const char? (I can't submit an edit with just one change.)
@ChristopheStrobbe What do you mean?
Well, conat in conat char ( &t )[11] in your answer.
I mean const is a type qualifier. But what is conat? A typo or something else?
@ChristopheStrobbe Oh, I am sorry. It is a typo.:)
|
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.

Comments

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.

2 Comments

Agreed, there's no point in having a template at all here. There's no common functionality.
Thanks! I will consider using overloaded functions instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.