当前位置: 首页 > 知识库问答 >
问题:

总是使用构造函数代替显式转换运算符

孟彦
2023-03-14

我有下面的课:

template <typename T1>
class Foo {
public:
    Foo(T1* obj) : obj(obj) {}

    template <typename T2>
    Foo(const Foo<T2>& other) : obj(other.obj) {}

    template <typename T2>
    explicit operator Foo<T2>() {
        return Foo<T2>(static_cast<T2*>(obj));
    }
    T1* obj;
};
class X {};
class Y : public X {};

int main() {
    Y obj;
    Foo<Y> y(&obj);
    Foo<X> x = y; // implicit cast works as expected.
    // y = x; // implicit conversion fails (as expected).
    // y = static_cast<Foo<Y>>(x); // conversion fails because constructor is
                                   // called instead of conversion operator.
}

共有1个答案

平俊茂
2023-03-14

对于static_cast >(x); ,您试图直接从x(它是foo )构造foo ,对于这样的上下文,转换构造函数比转换函数更好。

(强调我的)

如果转换函数和转换构造函数都可以用于执行某些用户定义的转换,则在复制初始化和引用初始化上下文中,转换函数和构造函数都将通过重载解析来考虑,但在直接初始化上下文中,只考虑构造函数

struct To {
    To() = default;
    To(const struct From&) {} // converting constructor
};

struct From {
    operator To() const {return To();} // conversion function
};

int main()
{
    From f;
    To t1(f); // direct-initialization: calls the constructor
// (note, if converting constructor is not available, implicit copy constructor
//  will be selected, and conversion function will be called to prepare its argument)
    To t2 = f; // copy-initialization: ambiguous
// (note, if conversion function is from a non-const type, e.g.
//  From::operator To();, it will be selected instead of the ctor in this case)
    To t3 = static_cast<To>(f); // direct-initialization: calls the constructor
    const To& r = f; // reference-initialization: ambiguous
}

您可以通过sfinae将转换构造函数从重载集中丢弃;即,仅当允许隐式转换基础指针时,才使其有效。

template <typename T2, typename = std::enable_if_t<std::is_convertible<T2*, T1*>::value>>
Foo(const Foo<T2>& other) : obj(other.obj) {}

活着

 类似资料:
  • 我有一个下面的例子(布尔类型过于安全): 众所周知,这样的代码包含一个错误:“无法转换’((int)((const A*)this)- 我想说: 由于指定的障碍,我不能简单地将的所有条目替换为我的用户代码中的超级安全的(这是mocked-对象),因为,例如,在使用了上述构造,将其视为隐式转换。类似的障碍并不唯一。

  • 但是,如果删除转换构造函数“fraction(int nn):nom(nn),den(1){}”或转换运算符“operator double()const{return double(nom)/den;}”,程序运行良好。 我想把分数转换成分数和分数。我可以做什么来既有转换,又有程序编译?

  • CLANG6、CLANG7和gcc 7.1、7.2和7.3都同意以下代码是有效的C++17代码,但在C++14和C++11下有歧义。MSVC2015和2017也接受它。然而,即使在C++17模式下,GCC-8.1和8.2也拒绝了它: 接受它的编译器选择模板化的显式转换函数。 拒绝它的编译器同意在以下两个方面存在歧义: null 以下是来自(接受代码)的错误:

  • 主要内容:转换构造函数,再谈构造函数,对 Complex 类的进一步精简在 C/ C++ 中,不同的数据类型之间可以相互转换。无需用户指明如何转换的称为自动类型转换(隐式类型转换),需要用户显式地指明如何转换的称为强制类型转换。 自动类型转换示例: 编译器对 7.5 是作为 double 类型处理的,在求解表达式时,先将 a 转换为 double 类型,然后与 7.5 相加,得到和为 13.5。在向整型变量 a 赋值时,将 13.5 转换为整数 13,然后赋给 a。整

  • 我正在学习这个rest json教程。在使用本教程中描述的maven创建项目后,我通过以下方式在dev模式下启动quarkus: 自动生成的项目带有一个示例类型,其中有JAX-RS注释。当我访问时,REST api工作正常,我在浏览器中看到了json负载。 当我修改

  • 问题内容: 要从Java 类中创建新对象,通常使用以下语句 我读过new运算符通过在堆中分配内存空间来创建新对象,但是我也读到调用构造函数会创建它。因此,这有点令人困惑。哪一个在创建对象?是 新 运算符还是默认构造函数? 问题答案: 具有与类同名的方法是合法的(尽管令人困惑),消除了任何歧义。指示JVM应该为给定的类和参数列表调用实例初始化方法,并返回已初始化的对象(在初始化方法的第一个(隐藏)参