MSVC:CRTP和带有模板参数包的递归函数的constexpr问题

我一直在写一些看起来像这样的代码:

#include <type_traits>

template <typename Derived, typename ...CastSeq> struct this_ptr {
private:
    template <typename T> using _identity = T; ///< Identity type.

    template <
        template <typename> typename Mod, typename Current
    > constexpr Mod<Derived> &_cast_sequence(Mod<Current> &ptr) const {
        return static_cast<Mod<Derived>&>(ptr);
    }
    template <
        template <typename> typename Mod, typename Current,
        typename Mid, typename ...Others
    > constexpr Mod<Derived> &_cast_sequence(Mod<Current> &ptr) const {
        static_assert(std::is_base_of_v<Current, Mid>, "Incorrect base type");
        return _cast_sequence<Mod, Mid, Others...>(static_cast<Mod<Mid>&>(ptr));
    }
public:
    constexpr Derived &get() {
        return _cast_sequence<_identity, this_ptr, CastSeq...>(*this);
    }
    constexpr const Derived &get() const {
        return _cast_sequence<std::add_const_t, this_ptr, CastSeq...>(*this);
    }
};

template <typename Derived> struct some_op : private this_ptr<Derived, some_op<Derived>> {
private:
    using _this = this_ptr<Derived, some_op<Derived>>;
    friend _this;
public:
    constexpr decltype(auto) get_x() const {
        return _this::get().x;
    }
};

template <typename T> struct object : public some_op<object<T>> {
    constexpr object(int xp) : x(xp) {
    }

    T x;
};

constexpr object<int> obj(3);
constexpr int ox = obj.get_x();

int main(int argc, char **argv) {
    return 0;
}

Basically, the this_ptr struct is used to obtain correctly-typed references to the derived class. The reason I'm using a sequence instead of a single type is that object may have several different ops that use this_ptr, which will result in ambiguous casts.

该代码在MinGW-g ++ 8.1.0上编译,但在最新版本的MSVC上无法编译,该版本失败,并且:

error C2131: expression did not evaluate to a constant
note: failure was caused by cast of object of dynamic type 'this_ptr<Derived,some_op<Derived>> *' to type 'const some_op<object<int>>'

我想知道这是由代码中的某些错误引起的,还是MSVC中的错误。

谢谢。

评论