如何从过载解析中删除函数

How do I remove a function from overload resolution?

本文关键字:删除 函数      更新时间:2023-10-16

使用赋值运算符时,我希望将类的实例转换为int。所以我写了这个代码:

struct X
{
    X() = default;
    X& operator=(int) { std::cout << "operator=(int)n"; return *this; }
    operator int() { return 0; }
};
int main()
{
    X a, b;
    a = b;
}

但它不会被调用。这是因为它调用了隐式复制赋值运算符,该运算符与参数完全匹配。我希望我的代码首先调用b上的转换运算符,然后将int返回值绑定到operator=()

是否有语法告诉编译器"不要考虑这个函数"?换句话说,如何从过载解析中删除函数?

我试过在复制赋值运算符上使用模板,这样我就可以执行SFINAE,但我想这只是创建了另一个函数,所以非模板函数总是更匹配。

隐式创建的赋值运算符保持最佳版本,即使您= delete它,也就是说,您会得到一个错误,而不是选择另一个版本。我建议简单地转发适当的逻辑,而不必费力地删除功能:

X& X::operator= (X const& other) {
    return (*this) = static_cast<int>(other);
}

诚然,这可能允许一个额外的隐式转换序列,否则可能不允许:

T -> X -> int

为了应对这种可能性,您可以添加另一个分配运算符:

template <typename T>
X& X::operator= (T&& other) {
    int arg = other;
    return (*this) = arg;
}

为了防止编译器创建默认函数,您必须声明主题私有(注意,您不需要定义主题)
要了解更多信息,我建议你阅读scot Meyers的有效c++第2章第6项。

只写

a = static_cast<int>(b);