简体   繁体   中英

Template argument deduction of string literal

Consider this simple function

template<typename T>
void func(const T& x) {std::cout<< typeid(T).name();}

now if I call function func("ddd") , what does T deduces to? . If there were no const in func 's parameter , T would be simply char [4] , Whats confusing me is addition of const , what does T deduces to ?

is it : const char [4] . If I change the parameter to T const &x (ie change order of const ) does deduction produces T to char const [4] ?

Can anyone explain argument deduction with string literals?

String literals are arrays of const characters.

A reference to string literal of 4 chars is of type char const (&)[4] .

const char [4] and char const [4] are same types!

char const (&)[N] , const char [N] and char const [N] all deduce to char const [N]

#include <iostream>

template<typename T>
void func1(T& x) {std::cout<< typeid(T).name()<<std::endl;}

template<typename T>
void func2(const T& x) {std::cout<< typeid(T).name()<<std::endl;}

template<typename T>
void func3(T const &x) {std::cout<< typeid(T).name()<<std::endl;}

int main()
{
    char c[4]= {'a','b','c','d'};
    const char c1[4]= {'a','b','c','d'};
    char const c2[4]= {'a','b','c','d'};

    func1("abcd"); //prints char const [4]
    func1(c); //prints char [4]
    func1(c1); //prints char const [4]
    func1(c2); //prints char const [4]

    func2("abcd"); //prints char const [4]
    func2(c); //prints char [4]
    func2(c1); //prints char const [4]
    func2(c2); //prints char const [4]

    func3("abcd"); //prints char const [4]
    func3(c); //prints char [4]
    func3(c1); //prints char const [4]
    func3(c2); //prints char const [4]

    return 0;
}

now if I call function func() , what does T deduces to?

If you call with a string literal, then T deduces to char const[N] .

If there were no const in func's parameter , T would be simply char [4]

If you mean that if you declared the parameter as T& x , then no: T would still be deduced to char const[N] if you call with a string literal.

If you mean that you call func with a non-const array, then yes: T would be deduced non-const.

If I change the parameter to T const &x

That changes nothing because const T & is just another way of writing T const & .

const usually refers to whatever is in front of it:

char const * -- pointer to constant char

char * const -- constant pointer to char

char const * const -- constant pointer to constant char

char Foo::bar() const -- constant member function returning char

etc.

The leading const is an exception dating back to the early days of C:

const char * <=> char const *

So, changing the ordering in your template would not change the type at all ( T const & <=> const T & ).

If you want to be consistent about const placement, use the trailing type exclusively, because it's the only way you can place const consistently.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM