【问题标题】:template partial specialization of static fields initialisation静态字段初始化的模板部分特化
【发布时间】:2011-01-05 14:57:01
【问题描述】:

我正在尝试以下操作:

struct MyType { };

template <typename T>
struct Test
{
    static const MyType * const sm_object;
};

template <>
struct Test<void>
{
    static const MyType * const sm_object;
};

template <typename T> const MyType * const Test<T>::sm_object = new MyType();
template <> const MyType * const Test<void>::sm_object = new MyType();

我将它包含在 2 个文件中 - a.cpp 和 b.cpp。我尝试编译并得到:

error C2998: 'const MyType *Test<void>::sm_object' : cannot be a template definition

我认为我的 C++ 语法不好,但我想不出我做错了什么。

我无法从变量定义中删除 template&lt;&gt;,因为我需要在多个翻译单元中使用它,这会导致链接错误。

我可以将字段放入基类并使用 CRTP 为每种类型创建一个新实例,然后专业化就不会妨碍,但为什么这种“直接”字段初始化不起作用?我一定是遗漏了一些语法。

我正在使用 VS2003 :(

【问题讨论】:

  • 答案是正确的,但我最终使用了一个包含 sm_object 的新结构 TestHolder,然后只需要对持有者类进行一次静态初始化,而不是部分专门化的。

标签: c++ templates static-members template-specialization


【解决方案1】:

从 g++ 来看,我认为您需要从该行中删除 template&lt;&gt; 并将其余部分放在一个源文件中(而不是在标题中)。因为它是一个特化,它就像一个普通的非模板静态,你没有在标题中定义。

在一些.C文件中:

const MyType * const Test&lt;void&gt;::sm_object = new MyType();

【讨论】:

  • 我希望把它做成一个只有头文件的组件,而不是有一个静态库来链接,所以我使用 CRTP 来实现它来保存静态对象。正确地标记为答案,这都是关于模板专业化的链接属性的。
【解决方案2】:

我相信你想做这样的事情

struct MyType { };

template <typename T>
struct Test
{
    static const MyType * const sm_object;
    static const MyType* set_object()
    {
        return nullptr;
    }
};

template <>
struct Test<void>
{
    static const MyType * const sm_object;
    static const MyType* set_object()
    {
        return new MyType();
    }
};

template <typename T> 
const MyType * Test<T>::sm_object = Test< T >::set_object();

【讨论】:

    【解决方案3】:

    我相信以下代码可能会引起一些人的兴趣:

    #include <stdio.h>
    template<class X,int Y>
    struct B
    {
      X content;
      static const int nr=Y;
    };
    
    int main(int, char**)
    {
      B<char,1> a;
      B<int,2> b;
      B<int,3> c;
      printf("%d, %d, %d\n",a.nr,b.nr,c.nr);
    }
    

    【讨论】:

    • 是的,这很有趣,但最初的问题更多是关于静态成员在显式特化下的链接阶段如何表现。
    猜你喜欢
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 2011-01-19
    相关资源
    最近更新 更多