隐式转换可能在模板替换期间发生
Implicit conversion may happen during template substitution?
我一直认为,对于模板化的函数,不可能发生隐式转换,实参的类型必须与模板化的形参类型完全匹配,否则模板实参推导将失败。
好吧,看来我错了。
考虑以下代码片段:
#include <iostream>
#include <type_traits>
template <class T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
class myInt
{
T val;
public:
myInt(T val) : val(val) {}
template <class U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
friend bool operator < (myInt<T> const &t, myInt<U> const &u)
{
return t.val < u.val;
}
};
int main()
{
myInt<int> i = 5;
myInt<int> j = 6;
// std::cout << (i < 6) << std::endl; // gives out compiler errors
std::cout << (5 < j) << std::endl; // works!
}
我不知道为什么第二个std::cout << (5 < j)
工作。这里肯定发生了隐式转换,我以为这是被禁止的。我更不确定为什么如果前者可以,std::cout << (i < 6)
就不能工作!
编辑:std::cout << (i < 6)
编译错误:
test.cpp: In function ‘int main()’:
test.cpp:23:21: error: no match for ‘operator<’ (operand types are ‘myInt<int>’ and ‘int’)
std::cout << (i < 6) << std::endl; // gives out compiler errors
^
test.cpp:23:21: note: candidate is:
test.cpp:12:17: note: template<class U, class> bool operator<(const myInt<int>&, const myInt<T>&)
friend bool operator < (myInt<T> const &t, myInt<U> const &u)
^
test.cpp:12:17: note: template argument deduction/substitution failed:
test.cpp:23:23: note: mismatched types ‘const myInt<T>’ and ‘int’
std::cout << (i < 6) << std::endl; // gives out compiler errors
这是"不对称"的原因是U
和T
在这方面有根本的区别:
template <class U, typename =
typename std::enable_if<std::is_integral<U>::value>::type>
friend bool operator < (myInt<T> const &t, myInt<U> const &u);
operator<
为模板,U
为该模板的参数。但是T
不是这个模板的参数。T
实际上是另一个模板myInt
的参数,因此在这个上下文中是固定的(为T=int
)。
实际上是这样的:
template <class U, /*SFINAE stuff*/>
friend bool operator < (myInt<int> const &t, myInt<U> const &u);
给定(5 < j)
,它知道如何将5
转换为t
的myInt<int> const &
。通过推断U
= ' int.
j
(myInt<int>
)传递给myInt<U> const &u
。但是(j<6)
不会工作,因为它不知道如何将6
传递给template<class U> ..... myInt<U> const &u
。特别是,它如何猜测哪个U
将使用必要的构造函数创建合适的myInt<U>
?也许myInt<int>
有string
构造函数,而myInt<string>
有int
构造函数!编译器不能知道。
我认为你可以这样做:
/* *NOT* a template */
friend bool operator < (myInt<T> const &t, myInt<T> const &u);
T instead of U ~~~~~~~~~^
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 从"wcslen"替换到"strnlen_s"时,用"const char*"进行类型转换是正确的方法吗?
- 替换 c++ 中的 c 样式强制转换 (long&)
- C++ 转换和 lambda - 替换循环
- 这个给定的代码应该将给定的数字转换为尽可能滞后的数字,no.by 用 9.It 替换合适的数字是行不通的
- 将类转换为过程 API C++:替换成员变量的常用方法?
- C++ 将双倍转换为字符并替换为标准::数组
- 有没有办法将模板的替换失败转换为布尔值(真/假)或标签(标准::true_type/标准::false_type)
- 用ATL 7.0字符串转换类和宏替换T2OLE
- 将utf8编码的字符串转换为本地8位编码的字符串,并将无法确定的字符替换为空白
- 将浮点数组转换为整数的最佳方式.[替换x64的asm代码]
- 我是否可以使用用户定义的转换将原始指针访问替换为通过类访问
- std::map通过转换替换现有元素
- thrust::device_vector使用自定义函子/谓词来替换或转换
- 将旧的Opencv代码转换为新的c++ API,替换cvGetSubRect
- 隐式转换可能在模板替换期间发生