另一个类/命名空间中函数模板的专业化? [英] Specialisation of function template in another class/namespace?

查看:21
本文介绍了另一个类/命名空间中函数模板的专业化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

I have written a function template that will iterate through a parent XML nodes children, retrieve the value of the child element and then push that child element value to a vector.

'retrieve the value' 部分也写成函数模板:

The 'retrieve the value' part is also written as a function template:

template <typename Type>
Type getXmlCollectionItem(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent);

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

There are specialisations for the retrieval part, for returning different types of child element value, e.g. std::string and other custom objects.

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

template <>
MyObject getXmlCollectionItem<MyObject>(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent);

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

This all works perfectly well, however it struck me that this would be very useful to have in a shared function library when dealing with tinyxml files.

问题:是否可以在一个命名空间中声明一个函数模板,例如namespace UtilityFunctions,它不了解诸如 'MyObject' 之类的特定对象类型,然后在其他具有特定对象类型的知识,例如 'MyObject'?

Question: Is it possible to declare a function template in one namespace e.g. namespace UtilityFunctions, which doesn't have any knowledge of specific object types like 'MyObject', and then declare and define specialisations of that function template in other namespaces which do have the knowledge of specific object types like 'MyObject'?

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

My hunch is that it isn't possible, but the concept of having a common function template seems to me to be useful enough for there to be an alternative way of getting close to the functionality I'm looking for...

如果任何术语不正确或解释不清楚,我们深表歉意.我已经围绕这个主题进行了大量研究(以达到在同一命名空间内工作函数模板专业化的点),但还没有找到明确的答案.

Apologies if any of the terminology is incorrect or explanation is unclear. I've done a lot of research around this topic (to get to the point of working function template specialisation within the same namespace) but found no definitive answer as yet.

推荐答案

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

It is not possible to write in one namespace a specialization of a template defined in another namespace (since that would not be specialization of that template, being defined in another namespace it would be a different template).

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

However it is perfectly OK to extend namespace where template has been originally defined, writing your specialization in totally separate source file.

所以这是你不能做的:

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

template <> int A::B::foo(int) {throw 0;}

您可以在 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;} 
                        ^

这是您可以做的:

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

namespace A { namespace B {
  template <> int foo(int) {throw 0;}
}}

有什么理由会造成问题吗?

Is there any reason why that would be a problem?

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

Also, if you delegate the work to a function associated with the object you are reading (either member or free function), you can depend on that function being found via ADL and called. Meaning you should be able to minimize the amount of such specializations like the above.

示例如下:

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;
}

编辑以添加示例

这篇关于另一个类/命名空间中函数模板的专业化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆