C++ 类和函数之间的模板缺乏正交性 //InternalTemplate.cpp:定义控制台应用程序的入口点。 // #包括“stdafx.h” 模板 结构左侧 { 静态无效插入(T*&新链接,T*&父项) { 父->getLeft()=新链接; newLink->parent=newLink; } }; 模板 结构链接 { T*父母; T*左; T*对u2;; T*&getParent()常量 { 返回父对象; } 模板 无效插件(链接*&newLink); }; 模板 模板 无效链接::插件(链接*&newLink)/
C++ 类和函数之间的模板缺乏正交性 //InternalTemplate.cpp:定义控制台应用程序的入口点。 // #包括“stdafx.h” 模板 结构左侧 { 静态无效插入(T*&新链接,T*&父项) { 父->getLeft()=新链接; newLink->parent=newLink; } }; 模板 结构链接 { T*父母; T*左; T*对u2;; T*&getParent()常量 { 返回父对象; } 模板 无效插件(链接*&newLink); }; 模板 模板 无效链接::插件(链接*&newLink)/,c++,templates,C++,Templates,$14/2- 模板声明只能作为命名空间范围或类范围声明出现在函数模板声明中,声明器id的最后一个组件应该是模板名称或运算符functionid(即,不是模板id)。[注意:在类模板声明中,如果类名是简单模板id,则声明声明类模板部分专用化(14.5.5)。-结束注意]” 该标准明确禁止使用这种语法。有关的更多信息,请参阅本标准。您需要专门研究链接结构,以便定义其模板成员函数 // InternalTemplate.cpp : Defines the entry point for the con
$14/2
-
模板声明只能作为命名空间范围或类范围声明出现在函数模板声明中,声明器id的最后一个组件应该是模板名称或运算符functionid(即,不是模板id)。[注意:在类模板声明中,如果类名是简单模板id,则声明声明类模板部分专用化(14.5.5)。-结束注意]”
该标准明确禁止使用这种语法。有关的更多信息,请参阅本标准。您需要专门研究
链接结构,以便定义其模板成员函数
// InternalTemplate.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
template<class T>
struct LeftSide
{
static void insert(T*& newLink, T*& parent)
{
parent->getLeft() = newLink;
newLink->parent = newLink;
}
};
template<class T>
struct Link
{
T* parent_;
T* left_;
T* right_;
T*& getParent()const
{
return parent_;
}
template<class Side>
void plugIn(Link<T>*& newLink);
};
template<class T>
template<class Side>
void Link<T>::plugIn(Link<T>*& newLink)//<<-----why can't I type
//void Link<T>::plugIn<Side>(Link<T>*& newLink)<---<Side> next to plugIn
{
Side::insert(newLink,this);
}
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
模板
模板
无效链接::插件(链接*&newLink)
{
Side::insert(newLink,this);
}
老实说,这让我的大脑有点爆炸。函数模板和类模板是互补的(我称它们为正交的,但你可以随意不同意),在模板元编程中,它们实际上用于正交的目的
类模板允许您在模板参数上进行模式匹配,即,它们提供部分专门化
相反,函数模板不允许部分专门化,但允许模板参数推断,这意味着您不必显式地编写模板参数(除了额外的参数,如示例中所示)
我认为,这解释了语法上的差异,因为它们可以实现的功能不同。此外,函数模板可以有重载,而类模板不能
结合这两个概念的方法是
1) 如果要对函数模板进行部分专门化,请使用带有静态非模板函数的帮助器类模板:
template<>
template<class Side>
void Link<int>::plugIn(Link<int>*& newLink)
{
Side::insert(newLink,this);
}
模板
结构doSomethingWithPointerHelper
{
静态无效行为(tx){…}
};
模板
结构doSomethingWithPointerHelper
{
静态无效行为(T*x){…}
};
//这就好像我们有一个部分专门化
//对于指针类型
模板
带指针的dosomething(T x)
{return dosomethingWithpointerHelper::act(x);}
在特定情况下,还有其他方法可以实现这一点,但这种方法总是有效的
2) 若要在构造复杂类时使用参数推断,请使用帮助器模板函数:
template <typename T>
struct doSomethingWithPointersHelper
{
static void act(T x) { ... }
};
template <typename T>
struct doSomethingWithPointersHelper<T*>
{
static void act(T* x) { ... }
};
// This acts as if we had a partial specialization
// for pointer types
template <typename T>
doSomethingWithPointers(T x)
{ return doSomethingWithPointersHelper<T>::act(x); }
模板
结构MyComplexClass
{ ... };
模板
MyComplexClass makeComplex(T,U)
{返回MyComplexClass(t,u);}
在标准库中,您可以找到使用此技术的make_pair
、bind1st
或mem_fun
。因此基本上没有保留语法或语法(根据决定)我说的对吗?@我们无能为力:是的,我们无能为力:)是的,我认为你文章中的引用与此上下文相关。void Link::plugIn
仅在MSVC++[上]编译。删除了我的答案,因为它不正确。
template <typename T, typename U>
struct MyComplexClass
{ ... };
template <typename T, typename U>
MyComplexClass<T, U> makeComplex(T t, U u)
{ return MyComplexClass<T, U>(t, u); }