为什么我们有一个类型不匹配
Why does we have a type mismatch?
我写了一个程序来查看如何在模板函数中推导字符串文字。
#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;
}
事实证明,只有对于 passByValue,字符串文字才推导出为const char*
类型。
在其他两种情况下(passByReferance 和 passByConstRef),如果我们应用于推导的参数,std::remove_reference_t
和 std::remove_const_t
,我认为得到的是const char*
,这是正确的吗?
当我使用std::decay_t
完全衰减时,我得到一个类型匹配,为什么会这样?
您传递const char[7]
而不是const char *
。数组和指针不是一回事。它们经常被混淆,因为数组很容易衰减到指向其第一个元素的指针。当按引用获取时,数组不需要衰减到指针。只有在第一种情况下,数组才需要衰减到指针。
以下测试为每种情况生成true
:
#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;
}
编辑:至于std::decay
,它显式地导致数组类型衰减到指针:
如果
T
将类型命名为"U
数组"或"对U
数组的引用",则成员 typedef 类型为U*
。
一些帮助程序,以更好地了解类型。CE:https://godbolt.org/z/6EFmIR
#include <type_traits>
template<class T>
struct Tis { Tis(); };
template<bool b>
struct Truth{ Truth(); };
template<typename T> void passByValue(T by_value)
{
Tis<T>{}; //call Tis<char const*>::Tis()
Truth<
std::is_same_v<char const*, decltype(by_value)>
>{}; // call Truth<true>::Truth()
}
template<typename T> void passByReferance(T &by_ref)
{
Tis<T>{}; // call Tis<char const [7]>::Tis()
Tis<decltype(by_ref)>{}; // call Tis<char const (&) [7]>::Tis()
Truth<
std::is_same_v<char const*, std::remove_reference_t<decltype(by_ref)>>
>{}; // call Truth<false>::Truth()
Tis<
std::remove_reference_t<decltype(by_ref)>
>{}; // call Tis<char const [7]>::Tis()
}
template<typename T> void passByConstRef(const T &const_ref)
{
Tis<T>{}; // call Tis<char [7]>::Tis()
Truth<
std::is_same_v<char const*, std::remove_const_t<std::remove_reference_t<decltype(const_ref)>>>
>{}; // call Truth<false>::Truth()
Tis<
std::remove_const_t<std::remove_reference_t<decltype(const_ref)>>
>{}; // call Tis<char [7]>::Tis()
}
void foo1(){
passByValue("string");
}
void foo2() {
passByReferance("string");
}
void foo3() {
passByConstRef("string");
}
相关文章:
- 将 unordered_map 与 Catch2 谓词一起使用时类型不匹配
- 重载函数的地址与所需类型不匹配
- 参数错误可能与类型不匹配有关?
- 调用子例程时类型不匹配
- POSIX(C )参数类型不匹配
- typedef 类型不匹配,将其传递到函数中
- 为什么此代码编译 (C++11) 而没有类型不匹配错误
- 候选模板被忽略:推断的类型与调整后的类型不匹配
- 内联 ASM:'out'的操作数类型不匹配
- 为什么我们有一个类型不匹配
- C++类和freeglut(参数类型不匹配)
- 警告 639:二进制操作中类型 'uint64' 的强类型不匹配
- 警告 634:相等或有条件的强类型不匹配(类型"bool")
- 不了解C++类型不匹配:const Foo* to Foo* const&
- 函数声明和定义的返回类型不匹配,编译器可以吗?
- 类型不匹配
- 返回指向常量getter的指针时,返回值类型与函数类型不匹配
- llvm pass replaceAllUses与类型不匹配?
- 参数类型不匹配(无效*)
- 重载运算符中的类型不匹配(写入管道)