函数模板在另一个类/命名空间中的专业化
Specialisation of function template in another class/namespace?
注意:这个问题与tinyxml的关系很松散,但包括这样的细节可能有助于更好地说明这个概念
我已经编写了一个函数模板,它将遍历父XML节点的子节点,检索子元素的值,然后将该子元素值推送到向量中。
"检索值"部分也被写成一个函数模板:
即
template <typename Type>
Type getXmlCollectionItem(
const char* elementName, TiXmlNode* child, TiXmlNode* parent);
检索部分有专门的功能,用于返回不同类型的子元素值,例如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);
这一切都很好,但我突然想到,在处理tinyxml文件时,在共享函数库中使用这一点非常有用。
问题:是否可以在一个命名空间中声明一个函数模板,例如namespace UtilityFunctions
,它对'MyObject'
等特定对象类型没有任何了解,然后在其他命名空间中声明和定义该函数模板的专业化,这些命名空间对'MyObject'
等特定对象类型有了解
我的直觉是这是不可能的,但在我看来,拥有一个通用功能模板的概念足够有用,可以有一种替代方式来接近我正在寻找的功能。。。
如果任何术语不正确或解释不清楚,请道歉。我围绕这个主题做了很多研究(以达到在同一名称空间内工作函数模板专业化的目的),但还没有找到确切的答案。
在一个命名空间中写入是不可能的是在另一个命名空间中定义的模板的专门化(因为这不是该模板的专业化,在另一命名空间中定义它将是不同的模板)。
然而,完全可以扩展最初定义模板的命名空间,在完全独立的源文件中编写您的专业化。
因此,以下是您不能做的事情:
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;}
}}
这会成为一个问题有什么原因吗?
此外,如果您将工作委托给与正在读取的对象相关联的函数(成员函数或自由函数),则可以依赖于通过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;
}
编辑以添加示例
这里的要点是"模板的每个声明都必须放在同一个命名空间中,就像任何其他命名实体的重复声明一样"
在不同的命名空间中声明/定义它是无效的,有关更多信息,请浏览常见问题中的第12点
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 在命名空间中定义函数还是限定函数
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- CUDA内核和数学函数的显式命名空间
- 嵌套的匿名命名空间
- CMakeLists.txt中的命名空间表示法
- 类是C++中的命名空间吗
- 在命名空间中使用全局命名空间中的函数
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- '使用命名空间{嵌套在另一个命名空间中的某个命名空间}"
- 是否可以将函数导入命名空间,但不能导出它?
- C++ C++类中的命名空间降级
- 如何使用 soong 命名空间来有条件地编译模块
- 使用 Clang++ 有没有办法将文件作为命名空间等包含?
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何在另一个名称空间内从另一个命名空间内明确专业化功能模板
- 函数模板在另一个类/命名空间中的专业化