在某些代码中,我正在审查我遇到了Clang和Gcc意见不同的情况。环顾了一会后,我似乎无法弄清楚谁是对的。

免责声明:我知道有一个更好的Singleton模式,但这是代码中使用的模式。

注意:

Ubuntu上的

  • gcc 7.4.0(无错误)
  • Ubuntu上的
  • clang 6.0.0(引发错误)
  • 对于所有C++ 11后的ISO版本似乎都存在差异,但是我没有更早尝试过。

  • foo.hh
    #include "sing.hh"
    
    class Foo {
        public:
        Foo();
        ~Foo();
        static Foo *getSingleton(){
            return singleton<Foo>::instance();
        }
    };
    

    foo.cc
    include "foo.hh"
    //removing this line results in the error for clang disappearing
    template<> singleton<Foo>::GetInstance singleton<Foo>::instance = nullptr;
    int main(){};
    

    sing.hh
    template<typename T>
    class singleton{
        typedef T *(*GetInstance)(void);
    public:
    
      static GetInstance instance;
    
    };
    

    结果:
    $ clang++  foo.cc
    foo.cc:3:56: error: explicit specialization of 'instance' after instantiation
    template<> singleton<Foo>::GetInstance singleton<Foo>::instance = nullptr;
                                                           ^
    ./foo.hh:10:32: note: implicit instantiation first required here
            return singleton<Foo>::instance();
                                   ^
    1 error generated.
    
    
    
    $ g++  foo.cc <- No Errors
    

    最佳答案

    两种编译器在技术上都没有错。该代码无效,但是不需要C++实现来提供有关此类错误的诊断消息。

    标准[temp.expl.spec]/6说(强调我的意思):



    您可以通过在sing.hh中的singleton定义之后立即声明显式专门化来解决此问题:

    struct Foo;
    template<> singleton<Foo>::GetInstance singleton<Foo>::instance;
    

    或者,如果您希望所有特化都初始化为空指针,则可以只在sing.hh中定义通用类模板的成员。则不需要显式的特化,除非您希望某些特定类型使用不同的初始化器。
    template<typename T>
    typename singleton<T>::GetInstance singleton<T>::instance = nullptr;
    

    关于c++ - Clang和Gcc在实例化后不同意显式特化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56351128/

    10-10 15:32