【问题标题】:implicit parameter in implicit conversion隐式转换中的隐式参数
【发布时间】:2015-07-01 13:15:00
【问题描述】:
#include <iostream>
using namespace std;

struct From{
    int i;
    From(){}
};

struct By{
    By(const From& f){}
};

struct To{
    To(const By& b){}
};

int main() {
    From f;
    To to = f;  // error: conversion from 'From' to non-scalar type 'To' requested
    // By by = f;
    // To to = by;
    return 0;
}

有什么方法可以在不修改 By 和 To 的情况下完成这项工作? 而且也没有这样做:

 By by = f;
 To to = by;

【问题讨论】:

  • 您是否希望编译器“理解”可以将From 转换为By,然后再转换为To?还是您根本不想通过By?
  • 如果围绕这些类型创建一个包装类,就可以解决这个问题。
  • @Amit 当然会使用By 的构造函数,但我希望编译器为我这样做!
  • @juanchopanza 隐式转换的要点是编译器为你做事,例如这里:ideone.com/OBSchN,在函数调用中,你不需要对象,编译器会为你转换,我这里需要的是双重转换,我知道他为什么不能这样做,但是可能有一个技巧

标签: c++ c++11


【解决方案1】:

只需在From中提供一个用户定义的转换运算符:

struct From
{
    int i;
    From(){}
    operator To() const
    {
         To to;
         //fill it
         return to;
    }
};

【讨论】:

    【解决方案2】:

    有什么方法可以在不修改 By 和 To 的情况下完成这项工作?

    是的。你可以给From一个转换运算符To()。这允许在单个用户定义的转换中将 From 转换为 To:

    struct From;
    struct By;
    
    struct To{
        To(const By& b){}
    };
    
    struct By{
        By(const From& f){}
    };
    
    struct From{
        int i;
        operator To() const { return To(By(*this)); }
        From(){}
    };
    

    【讨论】:

    • 永远不要说不可能,我知道它也会在这里创建一个B 对象,但我的意思是显式实例化,谢谢
    【解决方案3】:

    我不保证它的有用性,但是这个 sn-p 似乎可以满足您的要求:

    #include <iostream>
    using namespace std;
    
    struct From;
    
    struct By{
        By(const From& f){}
    };
    
    struct From{
        int i;
        From(){}
        operator By() {}
    };
    
    struct To{
        To(const By& b){}
    };
    
    int main() {;
        From f;
        To to {f};  // error: conversion from 'From' to non-scalar type 'To' requested
        // By by = f;
        // To to = by;
        return 0;
    }
    

    我在 From 中声明了一个隐式转换运算符,而没有触及 By 或 To;重新排列声明以安抚编译器;并将初始化语法从“to = f”更改为“to {f}”。

    请注意,这是不可扩展的,不能总是这样应用;当编译器试图将你给它的部分组合在一起时,可以发生的转换的数量和类型是有限的。

    编辑:正如已经向我指出的那样,这里唯一真正重要的变化是从复制初始化到直接初始化的切换。我将保留上面的代码,但在我的示例中不需要转换运算符。

    【讨论】:

    • 仅在 GCC 4.9 下; -Wall 抱怨未使用的参数和缺少返回语句,但没有别的。
    • 见ideone.com/vyz2VA。您的转换仅有效,因为您正在做其他事情。您甚至不需要转换。
    • 好吧,我现在觉得自己很愚蠢。我在没有考虑语义含义的情况下进行了更改;感谢您指出我的疏忽。
    • @acwaters:没必要觉得自己很愚蠢。 (几乎)从来没有。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    相关资源
    最近更新 更多