繁体   English   中英

模板转换函数为const-reference

[英]Template conversion function to const-reference

以下工作正常(正如人们所期望的那样):

struct X {};

struct A
{
  operator X const& () 
  {
    static const X value{};
    return value; 
  }
};

int main()
{
  A a;
  X x = a;
}

但这不是那么清楚:

template<typename T>
struct X {};

struct A
{
  template<typename T>
  operator X<T> const& () 
  {
    static const X<T> value{};
    return value; 
  }
};

int main() 
{
  A a;
  X<int> x = a;
}

GCC 4.9说error: conversion from 'A' to non-scalar type 'X<int>' requested而clang 3.4没有问题。 如果从转换函数中删除const& ,或者如果你写X<int> const &x = a那么GCC也很高兴。

因此,如果目标类型是const &模板类,并且您请求转换为该类的非const &对象,则GCC只能找不到转换函数。 这是正确的行为吗? 我试图阅读标准,但重载规则对我来说非常混乱。

是的,这是gcc中的一个错误。 这几乎就是核心DR976 ,唯一的区别在于它们的示例中目标类型是非类型:

struct F {
   template<class T>
   operator const T&() { static T t; return t; }
};

int main() {
   F f;
   int i = f;   // ill-formed
}

与您的示例一样,clang接受并且gcc拒绝此示例,无论选择何种标准版本方言。

请注意,由DR修改的条款(14.8.2.3 [temp.deduct.conv] )不区分类和非类目的地类型,因此该DR的分辨率同样适用于您的代码。

根据经修订的第14.8.2.3条,编制者应:

  • 确定P ,转换函数模板的返回类型, X<T> const &A ,所需的结果类型, X<int> ;
  • P剥离引用,得到X<T> const ;
  • P剥离cv资格,给出X<T> ;
  • T推导为int

我建议在https://gcc.gnu.org/bugzilla/上引用该DR提交错误报告。


因为在您转换为类类型的情况下,有一种解决方法可用:

X<int> x1 = a;          // fails
X<int> x2(a);           // OK
X<int> x3 = X<int>(a);  // also OK

在直接初始化中,考虑目标类型的构造函数(8.5p16); X<int>的默认复制构造函数采用类型为X<int> const&的参数,正如我们已经看到的那样gcc很乐意转换a

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM