在 visual studio 2019 中使用 boost::object_pool boost 版本 1.56 时出现问题
Problem using boost::object_pool boost version 1.56 with visual studio 2019
我正在尝试将旧项目的 boost::object_pool 用法转换为新的 visual studio 2019 项目,我使用的是 boost 版本 1.56
ObjectPool.h
class BOOST_OBJECT_POOL_CHECKER
{
boost::object_pool< T > m_sObjectPool;
template <class Arg1>
T* contruct(Arg1& sArg1)
{
T* temp = m_sObjectPool.construct(sArg1);
return temp;
}
}
MaterialServer.h
class MaterialServer
{
MaterialServer(dword serviceType, std::string path);
Material* NEW_MATERIAL();
}
Material.h
class Material
{
BOOST_OBJECT_POOL_CHECKER<Material> m_poolMATERIAL;
Material(MaterialServer* pMatServer);
}
Material.cpp
Material* MaterialServer::NEW_MATERIAL()
{
//Material* returnMaterial = m_poolMATERIAL.construct(this); << error on vs2019, not correct parameter
Material* returnMaterial = m_poolMATERIAL.construct(*this);
}
遇到第一个错误
boost_1_56\boost\pool\detail\pool_construct_simple.ipp(19,1): error C2664: 'Material::Material(MaterialServer*)': cannot convert argument 1 from 'const T0' to 'MaterialServer *'
ObjectPool.h(68): message : see reference to function template instantiation 'Material *boost::object_pool<T,boost::default_user_allocator_new_delete>::construct<Arg1>(const T0 &)' being compiled
with
[
T=Material,
Arg1=MaterialServer,
T0=MaterialServer
]
我需要升级boost版本吗?因为以前这段代码在 vs2008 上编译得很好,但在 vs2019 上没有编译,这个 c++11 标准让我很困惑
我可以解释一下这种行为吗?
坦率地说,这段代码无法在任何编译器下编译。
Note: I'm ignoring numerous typos, omitted semi-colons, omitted template
declarators, typedefs and access specifiers to focus on the real issues.
您超过了 *this
,即 Material&
。但是,contruct
[sic] 函数采用 MaterialServer*
.
所以,事实上,注释行更接近,并且有道理 IFF 它是 MaterialServer
的成员,而不是 Material
。
从逻辑上讲,material 服务器“创建新的 materials”更有意义,而且几乎可以工作:
class Material {
public:
Material(MaterialServer* pMatServer);
};
class MaterialServer {
BOOST_OBJECT_POOL_CHECKER<Material> m_poolMATERIAL;
public:
MaterialServer(dword serviceType, std::string path);
Material* NEW_MATERIAL();
};
Material* MaterialServer::NEW_MATERIAL()
{
Material* returnMaterial = m_poolMATERIAL.construct(this);
return returnMaterial;
}
我说 /almost/ 因为 construct
通过可变引用来获取它的参数。这不会在这里编译(this
不是可变左值)。
所以,解决这个问题:
template <typename Arg1> T* construct(Arg1 sArg1) {
return m_sObjectPool.construct(sArg1);
}
或者,更笼统地说:
template <typename... Arg> T* construct(Arg&&... sArg) {
return m_sObjectPool.construct(std::forward<Arg>(sArg)...);
}
我们得到“编译代码”。我们不能 link 它(未定义构造函数)。
再补充一些想象中的代码:
#include <boost/pool/object_pool.hpp>
#include <iomanip>
#include <iostream>
#include <string>
#include <atomic>
using dword = uint32_t;
template <typename T> class BOOST_OBJECT_POOL_CHECKER {
boost::object_pool<T> m_sObjectPool;
public:
template <typename... Arg> T* construct(Arg&&... sArg)
{
return m_sObjectPool.construct(std::forward<Arg>(sArg)...);
}
};
class MaterialServer; // forward declare
class Material {
public:
Material(MaterialServer* pMatServer);
};
class MaterialServer {
BOOST_OBJECT_POOL_CHECKER<Material> m_poolMATERIAL;
dword _serviceType;
std::string _path;
public:
MaterialServer(dword serviceType, std::string path)
: _serviceType(serviceType)
, _path(path)
{
}
Material* NEW_MATERIAL();
dword getServiceType() const { return _serviceType; }
std::string_view getPath() const { return _path; }
};
Material* MaterialServer::NEW_MATERIAL()
{
Material* returnMaterial = m_poolMATERIAL.construct(this);
return returnMaterial;
}
Material::Material(MaterialServer* pMatServer)
{
static std::atomic_int id{0};
std::cout << "Material " << id++ << " from server ("
<< pMatServer->getServiceType() << ", "
<< std::quoted(pMatServer->getPath()) << ")\n";
}
int main() {
MaterialServer a(123, "Material/a/resource");
MaterialServer b(234, "Material/b/resource");
a.NEW_MATERIAL();
a.NEW_MATERIAL();
b.NEW_MATERIAL();
a.NEW_MATERIAL();
}
版画
Material 0 from server (123, "Material/a/resource")
Material 1 from server (123, "Material/a/resource")
Material 2 from server (234, "Material/b/resource")
Material 3 from server (123, "Material/a/resource")
我正在尝试将旧项目的 boost::object_pool 用法转换为新的 visual studio 2019 项目,我使用的是 boost 版本 1.56
ObjectPool.h
class BOOST_OBJECT_POOL_CHECKER
{
boost::object_pool< T > m_sObjectPool;
template <class Arg1>
T* contruct(Arg1& sArg1)
{
T* temp = m_sObjectPool.construct(sArg1);
return temp;
}
}
MaterialServer.h
class MaterialServer
{
MaterialServer(dword serviceType, std::string path);
Material* NEW_MATERIAL();
}
Material.h
class Material
{
BOOST_OBJECT_POOL_CHECKER<Material> m_poolMATERIAL;
Material(MaterialServer* pMatServer);
}
Material.cpp
Material* MaterialServer::NEW_MATERIAL()
{
//Material* returnMaterial = m_poolMATERIAL.construct(this); << error on vs2019, not correct parameter
Material* returnMaterial = m_poolMATERIAL.construct(*this);
}
遇到第一个错误
boost_1_56\boost\pool\detail\pool_construct_simple.ipp(19,1): error C2664: 'Material::Material(MaterialServer*)': cannot convert argument 1 from 'const T0' to 'MaterialServer *'
ObjectPool.h(68): message : see reference to function template instantiation 'Material *boost::object_pool<T,boost::default_user_allocator_new_delete>::construct<Arg1>(const T0 &)' being compiled
with
[
T=Material,
Arg1=MaterialServer,
T0=MaterialServer
]
我需要升级boost版本吗?因为以前这段代码在 vs2008 上编译得很好,但在 vs2019 上没有编译,这个 c++11 标准让我很困惑
我可以解释一下这种行为吗?
坦率地说,这段代码无法在任何编译器下编译。
Note: I'm ignoring numerous typos, omitted semi-colons, omitted
template
declarators, typedefs and access specifiers to focus on the real issues.
您超过了 *this
,即 Material&
。但是,contruct
[sic] 函数采用 MaterialServer*
.
所以,事实上,注释行更接近,并且有道理 IFF 它是 MaterialServer
的成员,而不是 Material
。
从逻辑上讲,material 服务器“创建新的 materials”更有意义,而且几乎可以工作:
class Material {
public:
Material(MaterialServer* pMatServer);
};
class MaterialServer {
BOOST_OBJECT_POOL_CHECKER<Material> m_poolMATERIAL;
public:
MaterialServer(dword serviceType, std::string path);
Material* NEW_MATERIAL();
};
Material* MaterialServer::NEW_MATERIAL()
{
Material* returnMaterial = m_poolMATERIAL.construct(this);
return returnMaterial;
}
我说 /almost/ 因为 construct
通过可变引用来获取它的参数。这不会在这里编译(this
不是可变左值)。
所以,解决这个问题:
template <typename Arg1> T* construct(Arg1 sArg1) {
return m_sObjectPool.construct(sArg1);
}
或者,更笼统地说:
template <typename... Arg> T* construct(Arg&&... sArg) {
return m_sObjectPool.construct(std::forward<Arg>(sArg)...);
}
我们得到“编译代码”。我们不能 link 它(未定义构造函数)。
再补充一些想象中的代码:
#include <boost/pool/object_pool.hpp>
#include <iomanip>
#include <iostream>
#include <string>
#include <atomic>
using dword = uint32_t;
template <typename T> class BOOST_OBJECT_POOL_CHECKER {
boost::object_pool<T> m_sObjectPool;
public:
template <typename... Arg> T* construct(Arg&&... sArg)
{
return m_sObjectPool.construct(std::forward<Arg>(sArg)...);
}
};
class MaterialServer; // forward declare
class Material {
public:
Material(MaterialServer* pMatServer);
};
class MaterialServer {
BOOST_OBJECT_POOL_CHECKER<Material> m_poolMATERIAL;
dword _serviceType;
std::string _path;
public:
MaterialServer(dword serviceType, std::string path)
: _serviceType(serviceType)
, _path(path)
{
}
Material* NEW_MATERIAL();
dword getServiceType() const { return _serviceType; }
std::string_view getPath() const { return _path; }
};
Material* MaterialServer::NEW_MATERIAL()
{
Material* returnMaterial = m_poolMATERIAL.construct(this);
return returnMaterial;
}
Material::Material(MaterialServer* pMatServer)
{
static std::atomic_int id{0};
std::cout << "Material " << id++ << " from server ("
<< pMatServer->getServiceType() << ", "
<< std::quoted(pMatServer->getPath()) << ")\n";
}
int main() {
MaterialServer a(123, "Material/a/resource");
MaterialServer b(234, "Material/b/resource");
a.NEW_MATERIAL();
a.NEW_MATERIAL();
b.NEW_MATERIAL();
a.NEW_MATERIAL();
}
版画
Material 0 from server (123, "Material/a/resource")
Material 1 from server (123, "Material/a/resource")
Material 2 from server (234, "Material/b/resource")
Material 3 from server (123, "Material/a/resource")