为什么隐式转换不应用于模板化函数参数? [英] Why is implicit conversion not applied to templated function parameter?

查看:75
本文介绍了为什么隐式转换不应用于模板化函数参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一些模板方面遇到了问题,我将其缩小为以下示例(C ++ 17):

I'm having an issue with some template stuff that I've narrowed down to the following example (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>.无法编译.
  • item<T> has an implicit conversion operator to item<const T>, and
  • The conversion seems to work in conversionToConstRefWorks(), but
  • The conversion seems to be missed in butNotWhenTemplated(), where an item<const int> can be passed just fine but passing an item<int> fails to compile.

该示例的编译失败(GCC 9.3),其中:

Compilation of that example fails (GCC 9.3) with:

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);
      |                        ^

根本错误似乎是:

类型"const T"和"int"具有不兼容的简历限定符

types ‘const T’ and ‘int’ have incompatible cv-qualifiers

我理解从字面上看这意味着什么,但是我不明白为什么会这样.我的期望是 item< int>::运算符item< const int>()const 转换运算符将在调用 butNotWhenTemplated(i)时应用,就像调用 conversionToConstRefWorks(i)时所应用的那样,并且该 int会被选择为 T .

I understand what that means in a literal sense, but I don't understand why it is happening. My expectation is that the item<int> :: operator item<const int> () const conversion operator would be applied when calling butNotWhenTemplated(i) just as it was applied when calling conversionToConstRefWorks(i), and that int would be selected for T.

我的主要问题是:为什么不编译?

我的另一个问题是:出于本文范围之外的原因, butNotWhenTemplated 必须是模板,并且必须为所有指定< const T> > item 参数,调用时我无法明确指定模板参数.有没有办法使这些约束条件起作用?

My other question is: For reasons outside the scope of this post, butNotWhenTemplated has to be a template and has to specify <const T> to all item parameters, and I can't explicitly specify template parameters when calling it. Is there a way to make this work with those constraints?

此处位于ideone上(GCC 8.3).

Here it is on ideone (GCC 8.3).

推荐答案

item<int> i;
template <typename T> void butNotWhenTemplated (const item<const T> &) { }
butNotWhenTemplated(i); 

根据模板参数替换规则,没有 T item< const T> 的code>以匹配 item< int> .在考虑任何转换(内置或用户定义的转换)之前,此操作将以硬错误方式失败.

According to template argument substitution rules, no T could be found for item<const T> to match item<int>. This fails with an hard error way before any conversion (builtin or user-defined) could be considered.

类型推导不考虑隐式转换(上面列出的类型调整除外):这是超载解析的工作,稍后会发生.但是,如果对参与模板参数推导的所有参数推导成功,并且所有未推导的模板参数都被明确指定或默认,则将其余函数参数与相应的函数参数进行比较.

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.

这篇关于为什么隐式转换不应用于模板化函数参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆