Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不同编译器使用的不同强制转换运算符 < >在我尝试的所有编译器中,以下C++程序编译时没有警告(GCC 4.63,LLVM 3,ICC 131.1,SoalISStudio 12.1/12.3): struct类 { 模板 运算符T()常量{return 1;} 运算符int()常量{return 2;} }; 内部主(空) { C类x; 返回静态_-cast(x); } 但是,除了SoaliStudio编译器返回2,SalARISStudio(任一版本)都返回1,我认为这是最合理的结果。p>_C++_Templates_Casting_Operator Overloading_Overload Resolution - Fatal编程技术网

不同编译器使用的不同强制转换运算符 < >在我尝试的所有编译器中,以下C++程序编译时没有警告(GCC 4.63,LLVM 3,ICC 131.1,SoalISStudio 12.1/12.3): struct类 { 模板 运算符T()常量{return 1;} 运算符int()常量{return 2;} }; 内部主(空) { C类x; 返回静态_-cast(x); } 但是,除了SoaliStudio编译器返回2,SalARISStudio(任一版本)都返回1,我认为这是最合理的结果。p>

不同编译器使用的不同强制转换运算符 < >在我尝试的所有编译器中,以下C++程序编译时没有警告(GCC 4.63,LLVM 3,ICC 131.1,SoalISStudio 12.1/12.3): struct类 { 模板 运算符T()常量{return 1;} 运算符int()常量{return 2;} }; 内部主(空) { C类x; 返回静态_-cast(x); } 但是,除了SoaliStudio编译器返回2,SalARISStudio(任一版本)都返回1,我认为这是最合理的结果。p>,c++,templates,casting,operator-overloading,overload-resolution,C++,Templates,Casting,Operator Overloading,Overload Resolution,使用返回x.operator char()将导致所有编译器返回1 显然,自从弄明白这一点后,我一直在使用后一种符号。但是,我想知道哪种编译器是正确的,以及为什么。(有人会认为多数人占统治地位,但这仍然不能解释原因。) 这个问题似乎与SO问题有关,但这些“仅”给出了问题的解决方案,没有解释(我无论如何都能够应用于我的特定问题) 请注意,添加一个额外的重载强制转换操作符,例如操作符float()const{return 3;}会导致除SolarisStudio之外的所有编译器抱怨歧义。第一个是精确匹

使用
返回x.operator char()
将导致所有编译器返回1

显然,自从弄明白这一点后,我一直在使用后一种符号。但是,我想知道哪种编译器是正确的,以及为什么。(有人会认为多数人占统治地位,但这仍然不能解释原因。)

这个问题似乎与SO问题有关,但这些“仅”给出了问题的解决方案,没有解释(我无论如何都能够应用于我的特定问题)


请注意,添加一个额外的重载强制转换操作符,例如
操作符float()const{return 3;}
会导致除SolarisStudio之外的所有编译器抱怨歧义。

第一个是精确匹配,第二个需要转换。精确匹配优先于转换

你提到的其他问题大多与你的问题无关

一些建议:不要使用模板转换运算符。改为将其命名为
convert\u

应选择第一个(模板)重载

C++11标准第13.3.3/1段规定:

[…]一个可行函数
F1
被定义为比另一个可行函数更好的函数
F2
如果对于所有参数
i
ICSi(F1)
的转换顺序不比
ICSi(F2)
差,则

-对于某些参数
j
ICSj(F1)
是比
ICSj(F2)
更好的转换顺序,或者,如果不是这样

-上下文是通过用户定义转换进行的初始化(参见8.5、13.3.1.5和13.3.1.6)和 从
F1
返回类型到目标类型的标准转换顺序(即 实体被初始化)是一个比标准转换序列更好的转换序列 将
F2
返回到目标类型的返回类型
。[示例:

-结束示例]或,如果不是那样

-
F1
是一个非模板函数,
F2
是一个函数模板专用化,或者,如果不是这样

[……]

如您所见,第一个转换运算符是模板这一事实仅在标准转换序列从其返回类型(
char
,在本例中)到目标类型(
char
,在本例中)时才变得相关比从非模板重载的返回类型(
int
,在本例中)到目标类型(
char
,在本例中)的标准转换顺序要好

但是,从
char
char
的标准转换是完全匹配的,而从
int
char
的标准转换则不是。因此,§13.3.3/1第三项不适用,第二项不适用


这意味着应该选择刚刚在我的编译器G++4.8.0中测试的第一个(模板)重载

,它返回1。G++4.7.2也返回1。对于
操作符float()
,没有关于任何歧义的抱怨。g++返回一个从4.7开始的值。这是一个糟糕的代码。避免使用一般(非专业或不受限制的[例如,通过
std::enable_if
)模板转换运算符,因为这些运算符可能导致不需要的和未预见的转换。+1用于警告模板转换运算符。也许你可以解释一下为什么这是危险的,不是真的。它说模板专门化将被选中。但在op的例子中,没有专门化。编译器甚至不会开始创建模板,因为它已经找到了可以使用的匹配非模板强制转换。只有显式调用模板,或者没有其他匹配重载时,才会创建模板。编译器没有理由开始“猜测”匹配项template@YochaiTimmer:不,那不是真的。它不会实例化模板,但会执行模板参数推断,并查看模板是否是重载解析的可行候选模板。如果这是最可行的候选方案,它将选择并实例化它
struct CClass
{
  template<class T>
  operator T() const { return 1; }

  operator int() const { return 2; }
};

int main(void)
{
  CClass x;
  return static_cast<char>(x);
}
struct A {
    A();
    operator int();
    operator double();
} a;
int i = a; // a.operator int() followed by no conversion
           // is better than a.operator double() followed by
           // a conversion to int
float x = a; // ambiguous: both possibilities require conversions,
             // and neither is better than the other