【问题标题】:C++: specializing member requires template<> syntaxC++:专业化成员需要模板<> 语法
【发布时间】:2021-08-02 14:37:39
【问题描述】:

我正在尝试以下...

#include <iostream>

using namespace std;

template<class T>
class Singleton
{
private:
    class InstPtr
    {
    public:
        InstPtr() : m_ptr(0) {}
        ~InstPtr() { delete m_ptr; }
        T* get() { return m_ptr; }
        void set(T* p)
        {
            if (p != 0)
            {
                delete m_ptr;
                m_ptr = p;
            }
        }
    private:
        T* m_ptr;
    };

    static InstPtr ptr;
    Singleton();
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);

public:
    static T* instance()
    {
        if (ptr.get() == 0)
        {
            ptr.set(new T());
        }
        return ptr.get();
    }
};

class ABC
{
public:
    ABC() {}
    void print(void) { cout << "Hello World" << endl; }
};

当我尝试在 Visual Studio 中执行以下操作时,它可以正常工作。但是当我使用 g++ 编译时,它会因specializing member ‘Singleton&lt;ABC&gt;::ptr’ requires ‘template&lt;&gt;’ syntax 而失败。我在这里缺少什么?

#define ABCD (*(Singleton<ABC>::instance()))
template<> Singleton<ABC>::InstPtr Singleton<ABC>::ptr;
Singleton<ABC>::InstPtr Singleton<ABC>::ptr;

int main(void)
{
    ABCD.print();
    return 0;
}

【问题讨论】:

  • 无法重现,我也收到 msvc 错误:godbolt.org/z/ccdEfza5q
  • 你为什么重复Singleton&lt;ABC&gt;::InstPtr Singleton&lt;ABC&gt;::ptr;两次?
  • 你可以看看 Meyers 的 Singleton。
  • 为什么我得到未定义的引用`Singleton::ptr'
  • 为什么要为一种不再被推荐的模式编写如此复杂的代码,而当一个人可以制作单例时,代码却远少于此?

标签: c++ templates definition template-specialization explicit-specialization


【解决方案1】:
Singleton<ABC>::InstPtr Singleton<ABC>::ptr;

应该用于定义明确专门化的类模板的static 成员,例如

template<class T>
class Singleton
{
    ...
};

// explicit specialization
template<>
class Singleton<ABC>
{
private:
    class InstPtr
    {
        ...
    };

    static InstPtr ptr;
    
    ...
};

Singleton<ABC>::InstPtr Singleton<ABC>::ptr; // definition of the static member

LIVE


还有,explicit specialization of a static data member 喜欢

template<> Singleton<ABC>::InstPtr Singleton<ABC>::ptr;

是声明,但不是定义。

你需要为它指定初始化器,例如

template<> Singleton<ABC>::InstPtr Singleton<ABC>::ptr{}; // definition of the static member

LIVE

模板的静态数据成员的显式特化是 如果声明包含初始化程序,则定义;否则,它 是一个声明。这些定义必须使用大括号作为默认值 初始化:

template<> X Q<int>::x; // declaration of a static member
template<> X Q<int>::x (); // error: function declaration
template<> X Q<int>::x {}; // definition of a default-initialized static member

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 2022-01-24
    • 2013-09-24
    • 2020-07-18
    • 1970-01-01
    相关资源
    最近更新 更多