除了友元类之外,使方法显式化

问题描述 投票:3回答:1

我正在尝试创建一个默认显式的转换运算符,除了一些指定的类。

更准确地说,我有一个相对简单的类模板,其实例应该可以转换为其他类型(为简单起见,整个问题中的int)。但是,我希望默认情况下此转换是显式的,但仍然允许它为另一个类隐式,即作为模板参数传递的类。没有这最后一部分,这就是它的样子:

template<typename T>
class A {
public:
    A(int i) : i(i) {}
    explicit operator int() const {
        return i;
    }

private:
    int i;
};

现在,我希望能够在A a(2); int i = a;(它应该是一个类)的方法中编写类似T的东西。

我的第一个想法是利用朋友声明并声明转换运算符的私有重载。但是,不允许仅基于explicit进行重载。所以我尝试使用const代替它,它工作:

template<typename T>
class A {
public:
    A(int i) : i(i) {}
    explicit operator int() { // Public non-const
        return i;
    }

private:
    int i;

    operator int() const { // Private const
        return i;
    }

    friend T;
};

......直到没有。这只适用于使用非常量As,虽然我不打算使用const As,但我仍然希望它适用于所有情况。请注意,如果公共重载是const而私有不是,则仅使用const As。

Here is a demo显示它工作或不工作的情况。

我曾经想过使用volatiledemo),虽然它使它更好,但它仍然会导致同样的问题:它只在使用非易失性As时才有效。

有没有更好的方法呢?更一般地说,有没有办法在第一句话中解决问题?

c++ overloading c++17 friend explicit
1个回答
1
投票

显然没有令人满意的解决方案。 volatile选项似乎是最实用的,虽然它与volatile As不太一致,但额外的const_cast解决了这个问题。

template<typename T>
class A {
public:
    A(int i) : i(i) {}
    explicit operator int() const {
        return i;
    }

private:
    int i;

    operator int() const volatile {
        return static_cast<int>(const_cast<A const&>(*this));
        // or just
        // return i;
    }

    friend T;
};

Demo

正如Sneftel在评论中所述,访问权限倾向于以拉取(using)而非推送为基础授予。这可能就是为什么语言不提供改变转换语义的方法,具体取决于执行转换的类或块。

© www.soinside.com 2019 - 2024. All rights reserved.