【问题标题】:Accessibility error with boost addable and dllboost addable 和 dll 的可访问性错误
【发布时间】:2013-05-27 19:49:48
【问题描述】:

我在 Windows Vista 上使用 Visual Studio 2008,并将函数转换为调试 DLL。

编译器错误:

我在使用 boost::operator 模板时遇到可访问性错误:

error C2248: 'Field::Integer::Integer' : cannot access protected member declared in class 'Field::Integer'  
c:\program files\boost\boost_1_52_0\boost\operators.hpp(257) : while compiling class template member function 'Field::Integer boost::operator +(Field::Integer,const Field::Integer &)'
1>        c:\program files\boost\boost_1_52_0\boost\operators.hpp(836) : see reference to class template instantiation 'boost::addable1<T,B>' being compiled
1>        with
1>        [
1>            T=Field::Integer,
1>            B=boost::detail::empty_base<Field::Integer>
1>        ]
1>        see reference to class template instantiation 'boost::addable<T>' being compiled
1>        with
1>        [
1>            T=Field::Integer
1>        ]
1>        see reference to class template instantiation Field::Numeric<Value_Type,Descendant_Class>' being compiled
1>        with
1>        [
1>            Value_Type=int,
1>            Descendant_Class=Field::Integer
1>        ]

代码(简化为基本语句):

#ifndef FIELD_INTEGER_HPP
#define FIELD_INTEGER_HPP

#ifdef FIELD_EXPORTS
#define FIELD_API __declspec(dllexport)
#else
#define FIELD_API __declspec(dllimport)
#endif

#include "boost/operators.hpp"

namespace Field
{

template <class Value_Type, class FIELD_API Descendant_Class>
class FIELD_API Numeric
    : public boost::addable<Descendant_Class>,
      public boost::subtractable<Descendant_Class>,
      public boost::multipliable<Descendant_Class>,
      public boost::dividable<Descendant_Class>
{
  public:
                                Numeric(const Value_Type&   new_value = 0);
                                Numeric(const Numeric& fn);
    virtual                     ~Numeric();

    Descendant_Class            operator+=(const Descendant_Class& dc);
    Descendant_Class            operator-=(const Descendant_Class& dc);
    Descendant_Class            operator*=(const Descendant_Class& dc);
    Descendant_Class            operator/=(const Descendant_Class& dc);

    void                        clear_field(void);
    bool                        supports_value_as_string(void) const;
};


class FIELD_API Integer
    : public Field::Numeric<int, Field::Integer>
{
  public:
        //! Destructor
    virtual                     ~Integer();
  protected:
    //! Constructor
                                Integer(const int               new_value);

    //! Copy constructor
                                Integer(const Integer& fui);
};

} // End namespace Field

#endif  // FIELD_INTEGER_HPP

我的目标是将上述代码制作成可导出的调试 DLL 或发布 DLL。
代码在静态库设置中构建时没有错误。

问题:

在上述代码中,需要进行哪些修改才能将其转换为 Debug 或 Release DLL(Visual Studio 2008、Windows Vista、32 位)?

我搜索了网络和 StackOverflow,我只得到了使用模板的结果,没有将类作为模板参数和 DLL 传递。

【问题讨论】:

  • 为什么Field::Integer 构造函数是protected?您可能希望将其更改为 public 或将 friend class Numeric&lt;int, Integer&gt; 添加到 Integer 类定义中。
  • 构造函数是protected,因为我不希望它作为叶类。
  • 好吧,我不明白为什么它编译为静态库而不是 DLL,但友元类声明应该可以解决您的错误。
  • @rhalbersma:哪个班级应该成为朋友?
  • 我制定了一个答案,我的友谊评论不正确。

标签: c++ templates visual-studio-2008 boost dll


【解决方案1】:

发生错误是因为Numeric 继承自boost::addable(以及另外3 个相关类)。这会生成一个非成员函数operator+的签名

Field::Integer boost::operator +(Field::Integer,const Field::Integer &)

它采用左参数值的原因是为了优化右值引用和复制省略。这需要访问boost::operator+Integer 的复制构造函数,即protected,因此会出现错误。我不明白为什么编译为静态库对你有用,而 DLL 却不行。

对于这样的访问问题,推荐的方法是使复制构造函数public。不希望 Integer 作为叶类对我来说似乎是一个设计错误,因为如果这确实是您想要的,为什么您仍然希望能够将其用于加法和其他算术运算?

另一种方法是与boost::operator+(Integer, Integer const&amp;) 建立友谊。友谊路线不推荐,因为它依赖于boost::addable的实现。通常你会给boost::addable类授予友谊,但它的实现将使用非成员朋友函数operator+而不是成员函数operator+。你不应该让你自己的类Integer 依赖于这样的实现细节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-12
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    相关资源
    最近更新 更多