我正在为Boost Socket包装。我们有一个使用Boost套接字的类,但是我们需要对其进行包装,以便我们可以对其进行模拟,从而可以伪造从其进行的调用以进行单元测试。不是这个。
我写了一个包装程序,创造性地称为BoostSocketWrapper
,并为我们使用的套接字端点创建了端点。包装器保存真实套接字的实例,然后将调用传递到真实套接字。但是因为所有功能都是虚拟的,所以我们可以覆盖它们并使用Google Mock对其进行模拟。
我已经安装了所有端点,但是一旦编写了最后一个端点,我就会遇到一个新错误。 g ++声称找不到包装器的构造函数。如果我删除了必要的端点之一,它就不会抱怨,我只能认为这是因为它检测到其他错误,甚至还没有尝试构造它。
由于这是C ++ 11,因此我们为该类使用了唯一的指针。创建它的调用没有什么特别的:
theSocket = make_unique<BoostSocketWrapper>(ioService);
出于不清楚的原因,我们定义了自己的make_unique()
版本,但我知道make_unique()
直到C ++ 14才在C ++中定义。在代码的其他数百个地方也使用了它:
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
ioService
是一个传入值,当原始Boost套接字就位时,它可以完美工作。它定义为boost::asio::io_service
。包装器中的构造函数端点与Boost 1相同:
class BoostSocketWrapper {
public:
/**
* @brief Constructor that creates the Boost Socket
*
* @param ioService
*/
BoostSocketWrapper(boost::asio::io_service& ioService);
virtual ~BoostSocketWrapper() {}
...
}
但是g ++声称找不到它:
undefined reference to `speca::BoostSocketWrapper::BoostSocketWrapper(boost::asio::io_context&)'
我也只使用std :: unique_ptr尝试过,但这会产生相同的错误。
我整天都在撞我的头,但这没有帮助。这里的其他C ++编码人员也都不了解。这是BoostSocketWrapper
声明的要点,而标头包含在我尝试分配它的文件中:
#pragma once
#include <boost/asio.hpp>
namespace sprocketa {
class BoostSocketWrapper {
public:
BoostSocketWrapper(boost::asio::io_service& ioService);
virtual ~BoostSocketWrapper() {}
virtual void open( const boost::asio::ip::basic_endpoint<boost::asio::ip::udp>::protocol_type & protocol );
...
private:
// this constructs fine in the implementation
std::unique_ptr<boost::asio::ip::udp::socket> theSocket = nullptr;
}
} // namespace sprocketa
我们尝试从中分配它的类在同一名称空间中。我们正在将C ++ 11与g ++和Eclipse CDT用作IDE。
我在这里想念什么?
答案 0 :(得分:1)
它说:没有匹配呼叫...::unique_ptr(boost::asio::io_service&)
。这意味着您要将boost::asio::io_service&
传递给unique_ptr构造函数,而不是T
构造函数(应该是BoostSocketWrapper
)。
下面的最小示例无法重现该问题,因此您显然在代码的其他位置尝试从unique_ptr<>
引用初始化io_service&
而不是使用make_unique
。 (请注意,复制构造函数也可能从赋值语句或return语句中调用,因此请寻找意外的来源。)
#include <boost/asio.hpp>
#include <memory>
boost::asio::io_service ioService;
namespace sprocketa {
class BoostSocketWrapper {
public:
BoostSocketWrapper(boost::asio::io_service&) {}
virtual ~BoostSocketWrapper() {}
virtual void open(const boost::asio::ip::basic_endpoint<boost::asio::ip::udp>::protocol_type&) {}
private:
// this constructs fine in the implementation
std::unique_ptr<boost::asio::ip::udp::socket> theSocket = nullptr;
};
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
void foo() {
auto theSocket = make_unique<BoostSocketWrapper>(ioService);
}
} // namespace sprocketa
int main() {
sprocketa::foo();
}