另一个类/命名空间中的函数模板的专业化?

Ada*_*all 5 c++ templates tinyxml template-specialization

注意:这个问题只与tinyxml松散相关,但是包含这样的细节可能有助于更好地说明这个概念.

我编写了一个函数模板,它将遍历父XML节点子节点,检索子元素的值,然后将该子元素值推送到向量.

'检索值'部分也写为函数模板:

template <typename Type>
Type getXmlCollectionItem(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent);
Run Code Online (Sandbox Code Playgroud)

检索部分有专门化,用于返回不同类型的子元素值,例如std :: string和其他自定义对象.

template <>
std::string getXmlCollectionItem<std::string>(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent);

template <>
MyObject getXmlCollectionItem<MyObject>(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent);
Run Code Online (Sandbox Code Playgroud)

这一切都运行得很好,但是让我感到震惊的是,在处理tinyxml文件时,这对于共享函数库非常有用.

问题:是否可以在一个名称空间中声明一个函数模板,例如namespace UtilityFunctions,它不具有特定对象类型的任何知识'MyObject',然后在具有特定对象类型知识的其他名称空间中声明和定义该函数模板的特化喜欢'MyObject'

我的预感是它是不可能的,但是在我看来,拥有一个通用功能模板的概念足够有用,可以有一种替代方法来接近我正在寻找的功能......

如果任何术语不正确或解释不清楚,请道歉.我已经围绕这个主题做了很多研究(为了达到在同一名称空间内工作的函数模板专业化),但还没有找到明确的答案.

bro*_*ekk 5

不可能在一个名称空间中写入另一个名称空间中定义的模板的特化(因为那不是该模板的特化,在另一个名称空间中定义它将是一个不同的模板).

但是,在最初定义模板的地方扩展命名空间,在完全独立的源文件中编写专业化是完全可以的.

所以这是你不能做的:

namespace A { namespace B {
  template <typename T> int foo(T) {throw 1;}
}}

template <> int A::B::foo(int) {throw 0;}
Run Code Online (Sandbox Code Playgroud)

您可以在http://www.comeaucomputing.com/tryitout/看到上面的错误消息.

"ComeauTest.c", line 5: error: the initial explicit specialization of function
          "A::B::foo(T) [with T=int]" must be declared in the namespace
          containing the template
  template <> int A::B::foo(int) {throw 0;} 
                        ^
Run Code Online (Sandbox Code Playgroud)

这是你可以做的:

namespace A { namespace B {
  template <typename T> int foo(T) {throw 1;}
}}

namespace A { namespace B {
  template <> int foo(int) {throw 0;}
}}
Run Code Online (Sandbox Code Playgroud)

有什么理由可以解决这个问题吗?

此外,如果将工作委托给与正在读取的对象(成员或自由函数)相关联的函数,则可以依赖于通过ADL找到并调用的函数.这意味着您应该能够最大限度地减少上述此类专业化的数量.

这是一个例子:

namespace A { namespace B {
  template <typename T> int bar(T t) {return 0;}
  template <typename T> int foo(T t) {return bar(t);}
}}

namespace C {
  struct Bah {};
  int bar(Bah&) {return 1;}
}


int main(int argc,char** argv) 
{
  C::Bah bah;

  std::cout << A::B::foo(0) << std::endl;
  std::cout << A::B::foo(bah) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

编辑添加一个例子