我试图制作一个强大的typedef"模板,禁止在不同类型之间进行投射。在相关部分中,当前(工作)代码如下所示:
template<typename T, typename Tag>
struct strong_typedef_impl {
public:
//! ---- error struct (for better MSVC diagnostic)
struct error { friend struct strong_typedef_impl; private: error(){} ~error(){} };
//! ---- Construction
/*implicit*/ strong_typedef_impl(const strong_typedef_impl& other) : value(other.value) {}
/*implicit*/ template<typename U, typename UTag>
strong_typedef_impl(const strong_typedef_impl<U, UTag>&) : value() {
static_assert(false, "One must not cast one strong typedef to another");
}
//! ---- Type casting
/*explicit*/ inline operator T(void) const {return value;}
template<typename U, typename UTag>
/*implicit*/ operator strong_typedef_impl<U,UTag>(void) const {
static_assert(false, "One must not cast one strong typedef to another");
}
//! ---- Assignment
const strong_typedef_impl& operator=(const strong_typedef_impl& other) {
value = other.value; return *this;
}
const strong_typedef_impl& operator=(strong_typedef_impl&& other) {
value = other.value; return *this;
}
//template all-encompassing assignment to avoid implicit casting
template <typename U> error operator=(const U&) {
//static_assert(false, "One must not assign anything else to a strong typedef");
return error();
}
//...
};
第三个赋值运算符返回error
而不是static_assert
失败,因为项目通常由MSVC编译器从Qt Creator编译,当它看到static_assert
失败时,它只标记与assert
本身而不是调用者代码(在最好的情况下,这使得通过编译日志读取问题的人;在最坏的情况下,遇到问题的人只是认为这是我的错)。但返回的error
对象反而强制编译器在调用者代码中销毁它,从而以不太信息的消息为代价标记正确的行。
但是,我无法找出类似的铸造技巧。最初我认为编写构造函数
/*implicit*/ template<typename U, typename UTag>
strong_typedef_impl(const strong_typedef_impl<U, UTag>&, error e = error()) : value() { }
会强制来电者致电error()
,导致错误,但事实并非如此。
有没有人知道某些方法&#34;技巧&#34;编译器在这种情况下在调用者端制作错误的代码?或者可能是其他一些从MSVC编译器获得有意义诊断的方法?