16

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

4

4 回答 4

10

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

#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 时代的答案)

于 2011-09-29T23:47:28.473 回答
2

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

于 2010-06-19T19:59:19.453 回答
2

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

我唯一使用过的一致性是转换为伪布尔值(使用安全布尔成语),用于智能指针或代理,并且如前所述,我使用了一个技巧来实际阻止完整的布尔语义......

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

template <class T>
T to() const;

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

于 2010-06-20T10:41:41.127 回答
2

其实,我已经找到了办法;我们使用私有的、未使用的类来标记不应该存在的转换,并且我们使用boost::mpl::if_来选择是生成到 NoConversion 还是到所需类型的转换。

class A {
    class NoConversion { };
    template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}
于 2013-01-10T21:56:26.520 回答