enable_if和转换运算符?

时间:2010-06-19 16:15:26

标签: c++ boost casting operator-overloading enable-if

是否有机会将enable_if与类型转换运算符一起使用?看起来很棘手,因为返回类型和参数列表都是隐含的。

4 个答案:

答案 0 :(得分:8)

从我做过的小研究(忽略约翰内斯的c ++ 0x评论),我的答案是,它取决于你想要的enable_if。如果你希望T的转换操作存在或不存在T类型,那么似乎答案是否定的,C ++ 03中没有办法(正如Ugo所说)。但是,如果您需要enable_if来更改运算符的行为,具体取决于T的类型,那么有一种解决方法是调用启用的帮助函数( Matthieu建议称为to<T>

#include<iostream>
#include<boost/utility/enable_if.hpp>
#include<boost/type_traits/is_class.hpp>

struct B{
    B(const B& other){}
    B(){}
};

struct A{
    template<class T>
    T to(typename boost::enable_if_c<not boost::is_class<T>::value, void*>::type = 0){
        std::clog << "converted to non class" << std::endl;
        return T(0);
    }
    template<class T>
    T to(typename boost::enable_if_c<boost::is_class<T>::value, void*>::type = 0){
        std::clog << "conveted to class" << std::endl;
        return T();
    }
    template<class T>
    operator T(){
        return to<T>();
    }
};

int main(){
    A a;
    double d = (double)a; // output: "converted to non class"
    B b = (B)(a); // output: "converted to class"
    return 0;
}

为了记录,我对此感到沮丧了好几天,直到我意识到我希望enable_if不是SFINAE,而是因为编译时行为的改变。您可能还会发现这也是您需要enable_if的真正原因。只是一个建议。

(请注意,这是C ++ 98时代的答案)

答案 1 :(得分:2)

dixit documentation
似乎没有办法为转换运算符指定启用码。但是,转换构造函数可以将启用程序作为额外的默认参数。

答案 2 :(得分:2)

虽然我能理解这个问题的理论兴趣,但我个人不会尽可能地使用转换运算符。

我唯一使用一致性的是转换为伪布尔(使用Safe Bool惯用法),用于智能指针或代理,并且如上所述,我使用技巧来实际阻止完整的布尔语义。

如果我想要促进转换,我更喜欢以下方面的内容:

template <class T>
T to() const;

不受转换运算符的限制(在签名方面)的影响,并且需要显式调用,因为它更清晰。

答案 3 :(得分:2)

实际上,我找到了一条路;我们使用一个私有的,未使用的类来标记不应该存在的转换,我们使用boost::mpl::if_来选择是否生成转换为NoConversion或所需的类型。

class A {
    class NoConversion { };
    template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}