非命名空间范围内的显式特化

Mar*_*ark 121 c++ gcc templates

template<typename T>
class CConstraint
{
public:
    CConstraint()
    {
    }

    virtual ~CConstraint()
    {
    }

    template <typename TL>
    void Verify(int position, int constraints[])
    {       
    }

    template <>
    void Verify<int>(int, int[])
    {   
    }
};
Run Code Online (Sandbox Code Playgroud)

在g ++下编译它会产生以下错误:

非命名空间范围'类CConstraint'中的显式特化

在VC中,它编译得很好.任何人都可以让我知道解决方法吗?

Geo*_*che 92

在这种情况下,VC++是不兼容的 - 显式特化必须在命名空间范围内.C++ 03,§14.7.3/ 2:

应在模板所属的名称空间中声明显式特化,或者对于成员模板,在封闭类或封闭类模板所属的名称空间中声明.
应该在类模板所属的名称空间中声明类模板的成员函数,成员类或静态数据成员的显式特化.

另外,由于C++ 03,§14.7.3/ 3,你有一个问题就是你不能专门化成员函数而没有明确地专门化包含类,所以一个解决方案是Verify()提供一个可能是专门的免费函数:

namespace detail {
    template <typename TL> void Verify     (int, int[]) {}
    template <>            void Verify<int>(int, int[]) {}
}

template<typename T> class CConstraint {
    // ...
    template <typename TL> void Verify(int position, int constraints[]) {
        detail::Verify<TL>(position, constraints);
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 为什么语言开发人员会对程序员开发人员这样做?他们在想,"我们怎么能让这种语言更难以读写呢?" (11认同)
  • *在这种情况下不符合*:一如既往:)?模板和VC++不能很好地混合:/ (8认同)
  • 这个答案不再正确,现在在符合 C++14(及更高版本)编译器的类范围内允许专业化:https://wg21.cmeerw.net/cwg/issue727 (7认同)
  • 它在某种意义上是不合规的,它会让你做一些标准通常不允许的事情 - 这对于符合条件的代码来说不是问题(你编写这样的代码,对吧?〜).真正的一致性问题是它不会编译标准需要编译的东西,或者它的行为与指定的不同. (6认同)
  • 就像缺少两阶段查找所产生的细微陷阱......:| (2认同)
  • 由于这是目前谷歌的最高结果,我建议我们编辑这个答案以包含 Jean-Michaël Celerier 所说的内容。或者可能链接到[this](/sf/ask/3479502911/),这是最新的。最后,我不同意斯威夫特的说法,我认为这个裁决只会损害可读性。好吧,他确实说了“在某些情况下”。不管怎样,我认为现在更多的是 GCC 开发者的固执。MSVC 和 CLANG 都可以处理这些专业化。 (2认同)

Joh*_*itb 89

解决它的另一种方法是委托私有函数并重载该函数.这样,您仍然可以访问*this外部模板参数类型的成员数据.

template<typename T>
struct identity { typedef T type; };

template<typename T>
class CConstraint
{
public:

  template <typename TL>
  void Verify(int position, int constraints[])
  {
    Verify(position, constraints, identity<TL>());
  }

private:
  template<typename TL>
  void Verify(int, int[], identity<TL>)
  {

  }

  void Verify(int, int[], identity<int>)
  {

  }
};
Run Code Online (Sandbox Code Playgroud)

  • 如果我是你,我会选择这个答案.@Johannes:你的答案很完美,谢谢. (7认同)
  • 这个答案比被接受的答案更有用. (3认同)
  • 自C++ 11以来的任何变化都出现了? (3认同)

bop*_*bop 13

只需在类声明之外进行模板特化.gcc不允许内联模板专业化.

作为另一种选择,只是删除行模板<>似乎对我有用.


vit*_*tke 5

更好的是:您可以将部分专业化与默认模板参数结合使用。用这种方法对VC ++代码的修改很小,因为不需要修改对专用函数的调用。

template <typename TL, class Dummy=int>
void Verify(int position, int constraints[])
{
}

template <class Dummy=int>
void Verify<int, Dummy>(int, int[])
{
}
Run Code Online (Sandbox Code Playgroud)

  • 默认模板参数在C ++ 03中是不允许的,仅在C ++ 0x / 11中是不允许的。 (2认同)
  • 抱歉,我错了:您不能部分专门化一个函数。 (2认同)

归档时间:

查看次数:

75262 次

最近记录:

10 年,2 月 前