与递归类型别名相比,是否有更简洁的方法让包含类使用嵌套类中的类型别名?

时间:2016-03-22 21:09:23

标签: c++ typedef inner-classes

考虑以下简单类:

// Both type alias syntaxes included for reader convenience.

class External {
    // Nested struct.
    struct Internal {
        // Typedef:
#if (old compiler)
            // C++03-or-earlier compiler:
            typedef int field_t;
#else
            // C++11-or-later compiler:
            using field_t = int;
#endif

        // Field:
        field_t field;
    };

    // Private typedefs:
#if (old compiler)
        // C++03-or-earlier compiler:
        typedef std::vector<Internal> InternalVector;
#else
        // C++11-or-later compiler:
        using InternalVector = std::vector<Internal>;
#endif

    // Private fields:
    InternalVector vec;

    public:
        // Constructor & destructor:
        External() = default;
        ~External() = default;

        // Accessor & mutator:
        int getInternalField(size_t index) const;
        void setInternalField(size_t index, int val);
};

int External::getInternalField(size_t index) const {
    if (index >= vec.size()) { throw Tantrum; }

    return vec[index].field;
}

void External::setInternalField(size_t index, int val) {
    if (index >= vec.size()) { vec.resize(index + 1); }

    vec[index].field = val;
}

在这个类中,我们可以(并且应该)重新定义访问器和增变器以使用嵌套类&#39;输入别名而不是指定基础类型,以防将来更改:

class External {
    // ...

        // Accessor & mutator:
        Internal::field_t getInternalField(size_t index) const;
        void setInternalField(size_t index, Internal::field_t val);
};

External::Internal::field_t getInternalField(size_t index) const {
    // ...
}

void setInternalField(size_t index, External::Internal::field_t val) {
    // ...
}

然而,这比它需要的要冗长得多,所以最好将类型别名从Internal传播到External,使其成为public,这样外部代码可以更容易地使用类: / p>

class External {
    // ...

    public:
        // Public typedefs:
#if (old compiler)
            // C++03-or-earlier compiler:
            typedef Internal::field_t field_t;
#else
            // C++11-or-later compiler:
            using field_t = Internal::field_t;
#endif

        // Accessor & mutator:
        field_t getInternalField(size_t index) const;
        void setInternalField(size_t index, field_t val);
};

External::field_t getInternalField(size_t index) const {
    // ...
}

void setInternalField(size_t index, External::field_t val) {
    // ...
}

虽然这看起来很好,但重复使得代码不那么干净,特别是在混淆更复杂的类型时,和/或涉及模板时。

使用继承时,我们只需将代码从基类移植到using的派生类中,例如:

class ExternalDerived : public External {
    public:
        using External::field_t;

        field_t ret3() const;
};

ExternalDerived::field_t ExternalDerived::ret3() const {
    return 3;
}

不幸的是, 不能使用嵌套类。

class External {
    // Nested struct.
    struct Internal {
        // Typedef:
#if (old compiler)
            // C++03-or-earlier compiler:
            typedef int field_t;
#else
            // C++11-or-later compiler:
            using field_t = int;
#endif

        // ...
    };

    // ...

    public:
        using Internal::field_t; // Error: Internal isn't a base class.

    // ...
};

因此,考虑到上述所有问题,我的问题是:是否有一种简单,干净的方式来使用类似于using Base::member;语法的嵌套类中的类型别名,或者是递归类型别名(例如{ {1}})最干净的方式吗?

注意:这个问题并不是using field_t = Internal::field_t;typedef语法之间的区别,我只是将其包含在对这些语言更熟悉的人中。问题是对于嵌套类类型别名(例如,在此示例中为using)是否存在using Base::member;的等效项,或者是否是使用嵌套类的最简洁方法&#39;类型别名具有递归类型别名(例如,在此示例中为using Internal::field_t;)。

0 个答案:

没有答案