I have written a program to see, how string literals been deduced in template functions.
#include <iostream>
#include <string>
#include <type_traits>
template<typename T> void passByValue(T by_value)
{
std::cout << std::is_same_v<char const*, decltype(by_value)> << std::endl; // okay
}
template<typename T> void passByReferance(T &by_ref)
{
std::cout << std::is_same_v<char const*, std::remove_reference_t<decltype(by_ref)>> << std::endl;
}
template<typename T> void passByConstRef(const T &const_ref)
{
std::cout << std::is_same_v<char const*, std::remove_const_t<std::remove_reference_t<decltype(const_ref)>>> << std::endl;
}
int main()
{
std::cout << std::boolalpha;
passByValue("string"); // true: good
passByReferance("string");// false ??
passByConstRef("string"); // false ??
return 0;
}
It turns out that, only for the passByValue the string literals deduced to const char*
type.
In other two cases(passByReferance and passByConstRef), if we apply to the deduced arguments, std::remove_reference_t
and std::remove_const_t
, what I we suppose to get is const char*
, is that correct?
I get a type match when I do complete decay using std::decay_t
, why is that?
You are passing const char[7]
not const char *
. Arrays and pointers are not the same things. They are often confused because arrays easily decay to pointers to their first element. When taken by reference, arrays don't need to decay to pointers. Only in the first case does your array need to decay to a pointer.
The following tests produces true
for each case :
#include <iostream>
#include <string>
#include <type_traits>
template<typename T> void passByValue(T by_value)
{
std::cout << std::is_same_v<char const*, decltype(by_value)> << std::endl;
}
template<typename T> void passByReferance(T &by_ref)
{
std::cout << std::is_same_v<char const[7], std::remove_reference_t<decltype(by_ref)>> << std::endl;
}
template<typename T> void passByConstRef(const T &const_ref)
{
std::cout << std::is_same_v<char [7], std::remove_const_t<std::remove_reference_t<decltype(const_ref)>>> << std::endl;
}
int main()
{
std::cout << std::boolalpha;
passByValue("string");
passByReferance("string");
passByConstRef("string");
return 0;
}
Edit : As for std::decay
, it explicitly causes array types to decay to pointers :
If
T
names the type "array ofU
" or "reference to array ofU
", the member typedef type isU*
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With