转换运算符使用静态实现

我在这里提出的问题之后问这个问题。

这点很简单。 假设你有两类这种类型:

template < class Derived >
class Base {
...
operator const Derived&() const {
    return static_cast< const Derived& >(*this);
  }
...
};

class Specialization : public Base<Specialization> {
...
};

那么假设你有这样一个类型转换:

template < class T >
functionCall( const Base<T>& param) {
  const T & val(param);
  ...
}

问题是: 这种转换的标准符合行为应该是什么?

它应该与const T & val(static_cast<const T &> (param) )吗?还是应该递归迭代直到堆栈溢出? 请注意,我获得了使用GNU g++编译的第一行为,以及使用Intel icpc编译的第二行为。

我已经尝试了解标准(关于static_cast的第5.9节和关于转换的第12.3节),但由于缺乏经验,我无法找出答案。

我非常感谢任何花时间帮助我的人。


n3337中查看[expr.static.cast] (标准后的第一个工作草案):

2 /类型为“cv1 B ”的左值,其中B是类类型,可以转换为键入“对cv2 D引用”,其中D是从B派生(类10)的类,如果从“指向D “到”指针B “存在[...]

4 /否则,表达e可以显式转换到类型T使用static_cast形式static_cast<T>(e) ,如果声明T t(e); 是形成良好的,对于一些发明的临时变量t [..]

因此,我会解释gcc的行为是正确的,即表达式:

static_cast<Derived const&>(*this)

不应该调用递归operator Derived const& () const

我从其中存在的其他关键字推断出这一点,这意味着规则的排序。 规则2/应在规则4/之前尝试。


不建议使用隐式转换运算符。 在C ++ 11中,您可以将关键字explicit不仅添加到单个参数构造函数,还可以添加到转换运算符。 对于C ++ 03代码,您可以使用显式命名的转换函数,如self()down_cast()

此外,您似乎正在使用CRTP的Base类,即启用静态多态性。 这意味着你必须在编译时知道你正在调用哪个Derived类。 因此,除了实现CRTP接口外,您不必在任何公共代码中使用const Base& references。

在我的项目中,我有一个类模板enable_crtp

#include <type_traits>
#include <boost/static_assert.hpp>

template
<
        typename Derived
>
class enable_crtp
{
public:
        const Derived& self() const
        {
                return down_cast(*this);
        }

        Derived& self()
        {
                return down_cast(*this);
        }

protected:
        // disable deletion of Derived* through Base* 
        // enable deletion of Base* through Derived*
        ~enable_crtp()
        {
                // no-op
        }

private:
        // typedefs
        typedef enable_crtp Base;

        // cast a Base& to a Derived& (i.e. "down" the class hierarchy)
        const Derived& down_cast(const Base& other) const
        {
              BOOST_STATIC_ASSERT((std::is_base_of<Base, Derived>::value));
              return static_cast<const Derived&>(other);
        }

        // cast a Base& to a Derived& (i.e. "down" the class hierarchy)
        Derived& down_cast(Base& other)
        {
        // write the non-const version in terms of the const version
        // Effective C++ 3rd ed., Item 3 (p. 24-25)
        return const_cast<Derived&>(down_cast(static_cast<const Base&>(other)));
        }
};

这个类是由任何CRTP基类ISomeClass私有派生的,如下所示:

template<typename Impl>
class ISomeClass
:
    private enable_crtp<Impl>
{
public:
    // interface to be implemented by derived class Impl
    void fun1() const
    {
        self().do_fun1();
    }

    void fun2()
    {
        self().do_fun2()
    }

protected:
    ~ISomeClass()
    {}  
};

各种派生类可以按照他们自己特定的方式实现此接口,如下所示:

class SomeImpl
:
    public ISomeClass<SomeImpl>
{
public:
    // structors etc.

private:
    // implementation of interface ISomeClass

    friend class ISomeClass<SomeImpl>;

    void do_fun1() const
    {
        // whatever
    }

    void do_fun2() 
    {
        // whatever
    }

    // data representation
    // ...
};

外部的代码调用fun1class SomeImpl将获得委托给合适的常量或非const版本self()class enable_crtp和down_casting实施后do_fun1将被调用。 用一个体面的编译器,所有的indirections应该完全被优化。

注意:受保护的ISomeClassenable_crtp析构函数使得代码对于试图通过基指针删除SomeImpl*对象的用户是安全的。

链接地址: http://www.djcxy.com/p/10575.html

上一篇: Conversion operator implemented with static

下一篇: Wix 3.5 Icons on a push button control