【问题标题】:Labeling classes to disallow operations [duplicate]标记类以禁止操作[重复]
【发布时间】:2019-12-26 12:23:03
【问题描述】:

我希望能够使用编译时间信息来防止合并同一类的两个对象。特别是如果a 代表米,而b 使用厘米,我希望编译器不允许它们组合。

我可以通过受保护的继承来做到这一点吗?我需要使用标签吗?

这样的?

struct Meters{};
struct Centimeters{};

template < typename Units >
class DimensionedLength : protected Length {
 // What do I need to put in here?
}

int main(){

{
 Length a(0.0), b(1.0), c(2.0);

 std::cout << a+b << std::endl; // fine
 std::cout << a+c << std::endl; // fine
}


{
 DimensionedLength<Meters> a(0.0), b(1.0);
 DimensionedLength<Centimeters> c(2.0);

 std::cout << a+b << std::endl; // fine
 std::cout << a+c << std::endl; // compile error!
}

 return 1;
}

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    首先类模板应该是这样的:

    template<typename Units>
    struct DimensionedDouble {
        double value;
    };
    

    然后你需要为它实现所有的算术运算符,即:

    template<typename Units>
    DimensionedDouble<Units> operator+(DimensionedDouble<Units> x, DimensionedDouble<Units> y) {
        return {x.value + y.value};
    }
    

    等等。重载只能在Units匹配时调用,否则会报错。

    根据您希望语法与基本类型的接近程度,您可能还希望将 double 等的构造函数添加到您的类中。如上所示,只能从double(使用{...}= {...})进行聚合初始化。

    【讨论】:

    • 感谢您的评论,我试图简化事情,只是让它变得更加混乱。我解决了这个问题以尝试合并更多信息,特别是我试图包装的外部库中的一个类比 double 复杂一点(如果这意味着什么,则为 Eigen::Vector3d)。
    • 根据您的回复进行进一步搜索,这样的工作是否可行? stackoverflow.com/questions/3058561/…
    • @rhetorical5 不,这个答案根本不会阻止添加不同标记的类型。
    • @rhetorical5 如果您想可靠地防止类型之间的隐式转换或返回到底层类型,您需要按照我向您展示的方式复制整个接口。没有其他办法。您想要的也称为“强类型”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 2018-03-20
    • 1970-01-01
    • 2018-07-17
    • 2019-08-07
    • 1970-01-01
    • 2013-02-12
    相关资源
    最近更新 更多