为什么在C ++ Clang中实现CRTP会产生链接错误?

时间:2019-06-14 12:51:59

标签: c++ templates compiler-errors linker crtp

该问题与重复的相关问题不同-这是为了避免众所周知的解决方案,该解决方案将所有类显式实例化为.cpp文件中的模板参数,并将声明保留在标头中。使用CRTP可以通过在CRTP:CRTP()构造函数中声明应在.cpp文件中添加的内容相同,来简化此过程,但不要将其添加到每个.cpp文件中,所需的派生类应仅继承CRTP。

尝试在Clang中实现CRTP时出现链接错误(使用MVSC可以正常工作):

struct IPersistStream {
   ~IPersistStream() {}

   enum Direction {
       Read,
       Write
   };
};

template <class Derived>
struct CRTP
{
    CRTP()
    {
        auto _dummy_Read = &Derived:: template Persist<IPersistStream::Read>;
        auto _dummy_Write = &Derived:: template Persist<IPersistStream::Write>;
        _dummy_Read; _dummy_Write;
    }
};

这是派生类:

class DerivedClass: public CRTP<DerivedClass>
{
public:
    template <int direction>
    ErrorCode Persist(void *p, size_t sz);
};

实际的Persist函数的实现位于.cpp文件中,而声明位于.h文件中,因此链接程序会抱怨它们未解决。

起初,当我使用Derived :: Persist时,我也遇到了编译错误(MSVC也很好用),但是两者之间的 template 键区(类似于。和。 ->用法)解决了编译问题。

以下内容并未链接,就像MSVC一样:

1>Link : error : L0039: reference to undefined symbol `char const* DerivedClass::Persist<0>(PersistStream<0>&)' in file "DerivedClass.o"
1>Link : error : L0039: reference to undefined symbol `char const* DerivedClass::Persist<1>(HSL::PersistStream<1>&)' in file "DerivedClass.o"

有人建议为什么设计用于解决链接问题的模式实际上在MSVC中有效,而在Clang中不起作用?

谢谢

0 个答案:

没有答案