从 C++03 中的模板类中删除函数

问题描述 投票:0回答:1

我被困在 C++03 编译器中,并试图从(智能指针)模板类中消除“void”类型的函数。

MRE(从课堂上删除所有非必要信息):

template<typename T> struct EnableIfNotVoid { typedef T type; };
template<> struct EnableIfNotVoid<void> {};

template<typename T> class SmartPtr
{
    public:
        template<typename U = T>
        typename EnableIfNotVoid<U>::type &operator *(void) const
        {
            return *content;
        }

    private:
        T* content;
};

int main(int, char **)
{
    SmartPtr<int> works;
    SmartPtr<void> noWork;
    int& i = *works;
}

当通过 C++11 编译器运行它时(我不需要开始类),它可以完美地工作,但是当我尝试使用 C++03 编译器编译它时,我陷入困境,我得到了错误

default template arguments may not be used in function templates

我尝试过的其他事情(以及编译器抛出的错误):

没有默认参数:

no match for 'operator*' in '*works'

template<typename U>
typename EnableIfNotVoid<U>::type &operator *(void) const
{
    return content;
}

无模板:

no type named 'type' in 'struct EnableIfNotVoid<void>'

typename EnableIfNotVoid<T>::type &operator *(void) const
{
    return content;
}

没有 SFINAE(为了完整起见):

forming reference to void

T &operator *(void) const
{
    return *content;
}

我想避免必须专门化整个类(相当大),只是为了“省略”两个小函数,如果有一些更聪明的方法来做到这一点,我会非常感激。

c++ sfinae c++03
1个回答
1
投票

与稍微扩展的专业助手一起接近。

#include <boost/static_assert.hpp>

template<typename T>
struct SmartPtrImpl
{
    typedef T & Reference;

    template<typename Dummy>
    static Reference Deref(T * ptr)
    {
        return * ptr;
    }
};

template<>
struct SmartPtrImpl<void>
{
    typedef void Reference;

    template<typename Dummy>
    static Reference Deref(void *)
    {
        BOOST_STATIC_ASSERT_MSG((0 == sizeof(Dummy)), "SmartPtr<void> does not support dereference");
        return;
    }
};

template<typename T>
class SmartPtr
{
    public: typedef SmartPtrImpl<T> Impl;

    protected: T * m_ptr;

    public: SmartPtr(void): m_ptr() {}

    public: typename Impl::Reference
    operator *(void) const
    {
        return Impl::template Deref<int>(m_ptr);
    }
    // other stuff...
};

int main()
{
    SmartPtr<int> works; *works;
    SmartPtr<void> noWork; // *noWork;
}

在线编译器

取消注释

// *noWork;
会触发静态断言:

错误:“sizeof”对不完整类型“boost::STATIC_ASSERTION_FAILURE”的无效应用
23 | 23 BOOST_STATIC_ASSERT_MSG((0 == sizeof(Dummy)), "SmartPtr 不支持取消引用");

© www.soinside.com 2019 - 2024. All rights reserved.