我一直在写一些看起来像这样的代码:
#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 op
s 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中的错误。
谢谢。