C4150:删除指向不完整类型和PIMPL成语的指针
C4150: Deletion of pointer to incomplete type and PIMPL idiom
是否有任何方法可以在C 中使用模板类正确实现PIMPL成语?
例如,我有以下PIMPL类:
template <typename T> struct PrivateImplementation {
PrivateImplementation<T>(T* impl) : implementation(impl) {
}
~PrivateImplementation<T>() {
if (implementation != nullptr) delete implementation;
}
PrivateImplementation<T>(const PrivateImplementation<T>& c) = delete;
void operator=(const PrivateImplementation<T>& a) = delete;
PrivateImplementation<T>(PrivateImplementation<T>&& m) {
implementation = m.implementation;
m.implementation = nullptr;
}
T* operator->() const {
return implementation;
}
private:
T* implementation;
};
但是,当我像下面一样使用它时,编译器抱怨(警告)我要删除不完整的类型:
logger.h
class LoggerStream {
public:
LoggerStream(std::wstring componentName);
~LoggerStream();
LoggerStream(const LoggerStream&) = delete;
void operator=(const LoggerStream&) = delete;
LoggerStream(LoggerStream&&);
void Write(std::wstring message, const char* __function__, const char* __file__, int __line__) const;
void Write(std::wstring message) const;
private:
struct LoggerStreamImpl;
PrivateImplementation<LoggerStreamImpl> impl;
};
logger.cpp
struct LoggerStream::LoggerStreamImpl {
LoggerStreamImpl(std::wstring componentName) : componentName(componentName) { }
~LoggerStreamImpl() = default;
LoggerStreamImpl(const LoggerStreamImpl&) = delete;
void operator=(const LoggerStreamImpl&) = delete;
LoggerStreamImpl(LoggerStreamImpl&&);
const std::wstring componentName;
};
LoggerStream::LoggerStream(std::wstring componentName)
: impl(new LoggerStreamImpl { componentName }) { }
LoggerStream::~LoggerStream() { }
void LoggerStream::Write(std::wstring message, const char* __function__, const char* __file__, int __line__) const {
// Some implementation
}
void LoggerStream::Write(std::wstring message) const {
// Some implementation
}
我显然在.cpp中的LoggerStreamImpl
有一个定义的破坏者,那么什么给出了?
谢谢。
当我存储一个std :: unique_ptr时,我不希望完全可见的类型,例如pimpl,我使用一个自定义deleter,其中operator()在CPP中定义了cpp,班级可见。
它可以解决问题,并且通过链接时间优化,即使介绍的函数调用间接也可以优化,如果编译器认为它是相关的。
包含Logger.h的任何文件都尝试编译自身的模板。因此,可以说您有一个包含int main()
(或其他输入点)的main.cpp
文件,该文件包括Logger.h。main.cpp将看到logger.h,尝试对其进行解析,在解析它的过程中,它将尝试编译T = LoggerStreamImpl
的PrivateImplementation
模板的版本。如果您的编译器为C 11符合C 11,并且可以告诉您私人完成是外部定义的。
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 将 PIMPL 习惯用法与成员函数模板一起使用(无需预先了解所有可能的数据类型)
- C4150:删除指向不完整类型和PIMPL成语的指针
- 使用std::unique_ptr的C++Pimpl习语不完整类型
- 基于unique_ptr的pimpl类中的move构造函数是否需要一个完整的类型
- 正在将pImpl指针转换回调用方类型
- 使用shared_ptr处理不完全类型的Pimpl习语