链接隐式转换运算符

3

我有一个类需要进行一些隐式转换,包括中间值的转换,例如:

struct outer {
    struct inner {
        operator T() { return T(); }
    };
    operator inner() { return inner(); }
};

如果我有这个结构,那么是否总是有效的呢?例如:
void f(T t);
outer o;
f(o);

2
T是什么?一个模板类型吗? - Mooing Duck
2
@MooingDuck:一种类型。T是什么并不重要。这不是一个模板,因为我没有使用任何参数。 - Puppy
5
在标准中,最多允许进行一次标准转换(std-conversion)、一次用户定义转换(u-d conversion)再进行一次标准转换,而 f(o) 需要进行两次用户定义转换。请注意,翻译过程中不能改变原文意思。 - Gene Bushuyev
1
编译器只会自动执行一次隐式转换。通常最好避免使用隐式转换 - 它们往往会使代码更难理解和维护。 - mark
2个回答

11

§13.3.3.1.2 [over.ics.user] p1

用户定义的转换序列由初始标准转换序列、用户定义的转换函数(12.3)和第二个标准转换序列组成。

请注意,只会在隐式转换序列中考虑一个用户定义的转换函数。


是否有相应的位可以说明只会发生一个“用户定义的转换序列”? - ssube
@peachykeen 这就是参数传递的定义。对于类类型,它涉及一个用户定义的转换序列(如果参数类型与参数类型不同) ,然后将临时结果 T 的最终副本复制到类型为 T 的参数中。 - Johannes Schaub - litb

0

这个是有效的:

struct Foo {}; // renamed T in Foo to avoid confusion!

struct outer {
        struct inner {
                operator Foo() { return Foo(); }
        };

        operator inner() { return inner(); }

        template <typename T>
        operator T () {
                return operator inner();
        }
};

int main() {
        void f(Foo t);
        outer o;
        f(o);
}

但只是因为f没有重载,所以这并不是一个真正的解决方案。


如果可以接受的话,我会在外部类中创建Foo运算符。 - Puppy
我并不感到惊讶这不是"可接受"的,但这是我得到的最好的"修复"。 - curiousguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接