我遇到了一些模板问题,这些问题已缩小到以下示例(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);
}
在该示例中:item<T>
对item<const T>
和conversionToConstRefWorks()
中起作用,但是butNotWhenTemplated()
中进行转换,其中item<const int>
可以很好地传递,但传递item<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);
| ^
根本错误似乎是:types ‘const T’ and ‘int’ have incompatible cv-qualifiers
我理解从字面上看这意味着什么,但我不明白为什么会这样。我的期望是,调用
item<int> :: operator item<const int> () const
时将应用butNotWhenTemplated(i)
转换运算符,就像调用conversionToConstRefWorks(i)
时所应用的那样,并且int
将选择T
。我的主要问题是:为什么不编译?
我的另一个问题是:出于本文范围之外的原因,
butNotWhenTemplated
必须是模板,并且必须为所有<const T>
参数指定item
,并且在调用它时我无法显式指定模板参数。有没有办法使这些约束条件起作用?Here it is on ideone(GCC 8.3)。
最佳答案
item<int> i;
template <typename T> void butNotWhenTemplated (const item<const T> &) { }
butNotWhenTemplated(i);
根据template argument substitution规则,找不到与T
匹配的item<const T>
的item<int>
。在考虑任何转换(内置或用户定义的)之前,这将以硬错误方式失败。Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later. However, if deduction succeeds for all parameters that participate in template argument deduction, and all template arguments that aren't deduced are explicitly specified or defaulted, then the remaining function parameters are compared with the corresponding function arguments.
关于c++ - 为什么隐式转换不应用于模板化函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65401573/