【问题标题】:how can I use std::enable_if in a conversion operator?如何在转换运算符中使用 std::enable_if?
【发布时间】:2013-08-07 09:56:26
【问题描述】:

基本上我希望我的范围类型可以从Range<const char> 隐式转换为Range<const unsigned char>。 std::enable_if 似乎是不可能的,因为该函数没有参数并且没有返回。有什么解决办法?

这基本上是我尝试过的:

template<typename T>
class Range{
    T* begin_;
    T* end_;
public:
    Range(T* begin,T* end):begin_{begin},end_{end}{}
    template<int N>
    Range(T (&a)[N]):begin_{static_cast<T*>(&a[0])},end_{static_cast<T*>(&a[N-1])}{}
    T* Begin(){return begin_;}
    T* End(){return end_;}
    operator typename std::enable_if<std::is_same<T,const char>::value,Range<const unsigned char>&>::Type (){
        return *reinterpret_cast<Range<const unsigned char>*>(this);
    }
};

【问题讨论】:

  • 为什么不用std::is_same&lt;&gt; 而不是Loki::IsSameType&lt;&gt; ??
  • 我在 ARM 皮质上编程裸机,起初让 Loki 工作更容易,所以很好,我改变了它;)
  • 您真的需要转换运算符吗?或者你可以和operator= 和构造函数一起生活吗?
  • std::enable_if 有一个成员类型(def)type(小t),而不是Type
  • 您可以使用std::conditionalRange&lt;const unsigned char&gt;void 之间切换转换运算符(根据clang++,void 的转换运算符是合法的且从未使用过)。或者你可以使用类模板的特化。

标签: c++ metaprogramming sfinae enable-if


【解决方案1】:

使用默认为 T 的虚拟参数使其成为模板 - 这是为了将类型推导推迟到函数被实例化的点,否则 SFINAE doesn't work。然后你在另一个参数的默认值中做你想要的检查。

template<
    typename U = T,
    typename = typename std::enable_if< std::is_same<U,const char>::value >::type
>
operator Range<const unsigned char>() {
    return *reinterpret_cast<Range<const unsigned char>*>(this);
}

【讨论】:

  • @joik 感谢您指出我与转换运算符冲突的错误,我将其删除。
  • 还要注意有些不寻常的“typename = typename ...”。如果我使用类型名称,它对我不起作用。
  • C++14 引入了std::enable_if_t,它是typename std::enable_if&lt;...&gt;::typestd::is_same_v 的别名std::is_same&lt;...&gt;::value
猜你喜欢
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
相关资源
最近更新 更多