如何在调用构造函数或类型转换时强制调用者错误?

时间:2017-06-15 18:03:05

标签: c++ compiler-errors strong-typing

我试图制作一个强大的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编译器获得有意义诊断的方法?

0 个答案:

没有答案