Jas*_*n C 6 c++ gcc templates implicit-conversion c++17
我遇到了一些模板内容的问题,我已将范围缩小到以下示例 (C++17):
template <typename T> struct item {
operator item<const T> () const { return item<const T>(); }
};
void conversionToConstRefWorks (const item<const int> &) { }
template <typename T>
void butNotWhenTemplated (const item<const T> &) { }
int main () {
item<int> i;
item<const int> ci;
// these all compile fine:
conversionToConstRefWorks(ci);
conversionToConstRefWorks(i);
butNotWhenTemplated(ci);
// but this one fails:
butNotWhenTemplated(i);
}
Run Code Online (Sandbox Code Playgroud)
在那个例子中:
item<T>
有一个隐式转换运算符 to item<const T>
,和conversionToConstRefWorks()
,但是butNotWhenTemplated()
,其中 anitem<const int>
可以很好地传递但传递 anitem<int>
无法编译。该示例的编译失败(GCC 9.3):
g++ --std=c++17 -W -Wall -pedantic -Wno-unused-variable const_interop.cpp -o const_interop
const_interop.cpp: In function ‘int main()’:
const_interop.cpp:54:24: error: no matching function for call to ‘butNotWhenTemplated(item<int>&)’
54 | butNotWhenTemplated(i);
| ^
const_interop.cpp:40:6: note: candidate: ‘template<class T> void butNotWhenTemplated(const item<const T>&)’
40 | void butNotWhenTemplated (const item<const T> &) {
| ^~~~~~~~~~~~~~~~~~~
const_interop.cpp:40:6: note: template argument deduction/substitution failed:
const_interop.cpp:54:24: note: types ‘const T’ and ‘int’ have incompatible cv-qualifiers
54 | butNotWhenTemplated(i);
| ^
Run Code Online (Sandbox Code Playgroud)
根错误似乎是:
类型“const T”和“int”具有不兼容的 cv 限定符
我理解字面上的意思,但我不明白为什么会发生这种情况。我的期望是,item<int> :: operator item<const int> () const
在调用时会应用转换运算符,butNotWhenTemplated(i)
就像在调用时应用一样conversionToConstRefWorks(i)
,并且int
会为T
.
我的主要问题是:为什么不编译?
我的另一个问题是:出于本文范围之外的原因,butNotWhenTemplated
必须是模板并且必须指定<const T>
所有item
参数,并且在调用它时我无法明确指定模板参数。有没有办法在这些约束下进行这项工作?
这是在ideone(GCC 8.3)上。
item<int> i;
template <typename T> void butNotWhenTemplated (const item<const T> &) { }
butNotWhenTemplated(i);
Run Code Online (Sandbox Code Playgroud)
根据模板参数替换规则,没有T
能为找到item<const T>
匹配item<int>
。在可以考虑任何转换(内置或用户定义)之前,这会以硬错误方式失败。
类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后发生。但是,如果所有参与模板实参推导的参数推导成功,并且所有未推导的模板参数都被明确指定或默认,则剩余的函数参数将与相应的函数参数进行比较。