【发布时间】:2018-12-18 04:06:18
【问题描述】:
我有这种结构:
静态库 A
interface.h
class Interface
{
public:
virtual ~Interface() // no pure virtual dtor
virtual void pureMethod1() = 0;
virtual void pureMethod2() = 0;
virtual void virtualMethod1();
virtual void virtualMethod2();
};
interface.cpp
include "interface.h"
Interface::~Interface() = default;
Interface::virtualMethod1() {}
Interface::virtualMethod2() {}
使用 A 的静态库 B
BaseT.h
#include "interface.h"
template<class T>
class BaseT final : public Interface
{
static_assert(false, "can't use this specialization");
};
specialized1.h
#include "baset.h"
using MyType = BaseT<CustomClass1>;
template<>
class BaseT<CustomClass1> : public Interface
{
public:
BaseT() = default;
void pureMethod1() final {}
void pureMethod2() final {}
};
specialized2.h
#include "baset.h"
using MyType = BaseT<CustomClass2>;
template<>
class BaseT<CustomClass2> : public Interface
{
public:
BaseT() = default;
void pureMethod1() final {}
void pureMethod2() final {}
};
我在两个完全专业化的课程中都收到了来自 clang 的警告:
警告:'BaseT 没有外联的虚拟方法定义:它的 vtable 将在每个翻译单元中发出'
为什么会出现这个警告?我没有任何纯虚拟析构函数,并且在基类中提供了默认析构函数。以及由于我使用的是模板,如何避免使用外联的虚拟方法?
【问题讨论】:
-
您应该简化此代码以制作 mcve。由于 static_assert 失败和其他问题,现在它不会编译。
-
@PasserBy 这是一个不同的问题
-
@V.Kravchenko 是的,我的错误,没有通读。
-
唯一的问题是所有的目标文件都会稍大一些。可执行文件中仍然只有一个 vtable。链接器负责处理(但可能需要更长的时间才能将其全部整理出来)。
-
static_assert(false, "can't use this specialization");使您的代码格式错误,您必须执行template <typename T> struct always_false : std::false_type {}; static_assert(always_false<T>::value, "can't use this specialization");之类的操作(看起来相似但正确)。