我在Windows Vista上使用Visual Studio 2008,并将函数转换为构建为调试DLL。
我在使用boost :: operator templates时遇到了辅助功能错误:
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
我的目标是将上面的代码变成可导出的Debug DLL或Release DLL 代码构建时静态库设置中没有错误。
在上面的代码中,将它变成Debug或Release DLL(Visual Studio 2008,Windows Vista,32位)需要进行哪些修改?
我搜索了网络和StackOverflow,我只获得使用模板的结果,而不是将类作为模板参数和DLL传递。
答案 0 :(得分:1)
发生错误是因为Numeric
继承自boost::addable
(以及另外3个相关类)。这将生成签名
operator+
Field::Integer boost::operator +(Field::Integer,const Field::Integer &)
它的左参数by-value的原因是优化rvalue引用和copy-elision。这需要boost::operator+
访问Integer
的副本构造函数protected
,因此您会收到错误消息。我不明白为什么编译为静态库对你有用,而DLL却没有。
对于这样的访问问题,建议的方法是创建复制构造函数public
。不希望Integer
作为叶子类对我来说似乎是设计错误,因为如果这真的是你想要的,为什么你仍然希望能够将它用于添加和其他算术运算?
另一种方法是向boost::operator+(Integer, Integer const&)
授予友谊。不推荐友谊路线,因为它取决于boost::addable
的实施。通常,您会向类boost::addable
授予友谊,但是它的实现将使用非成员友元函数operator+
而不是成员函数operator+
。您不应该让自己的类Integer
依赖于此类实现细节。