gpt4 book ai didi

c++ - 总是使用构造函数而不是显式转换运算符

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:34:27 25 4
gpt4 key购买 nike

我有以下类(class):

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;
};

第二个构造函数的目的是从 Foo<X> 隐式转换至 Foo<Y>如果从 X* 进行隐式转换,则允许至 Y*是允许的。

转换运算符允许从 Foo<X> 进行显式转换至 Foo<Y>使用来自 X* 的显式转换至 Y* .

但我注意到转换运算符从未被使用过。编译器总是使用第二个构造函数,即使我进行显式转换也是如此。如果基础类型的隐式转换是不可能的,这会导致错误。

下面的代码可以用来测试上面的类。

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.
}

有没有办法让编译器使用转换运算符进行显式转换?

最佳答案

对于 static_cast<Foo<Y>>(x); ,你正在尝试构建一个 Foo<Y>来自 x (这是一个 Foo<X> )直接,对于这样的上下文,转换构造函数优于 conversion function .

(强调我的)

If both conversion functions and converting constructors can be used to perform some user-defined conversion, the conversion functions and constructors are both considered by overload resolution in copy-initialization and reference-initialization contexts, but only the constructors are considered in direct-initialization contexts.

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) {}

LIVE

关于c++ - 总是使用构造函数而不是显式转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45130166/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com