在C ++中对类模板进行完全专业化时,为什么不必定义相同的成员?

问题描述

| 我很惊讶地发现以下编译:
#include <iostream>

using namespace std;

template<typename T>
class SomeCls {
public:
  void UseT(T t) {
    cout << \"UseT\" << endl;
  }
};

template<>
class SomeCls<int> {
  // No UseT? WTF?!??!?!
};

int main(int argc,char * argv[]) {
  SomeCls<double> d;
  SomeCls<int> i;

  d.UseT(3.14);
  // Uncommenting the next line makes this program uncompilable.
  // i.UseT(100);

  return 0;
}
为什么允许这样做?
class SomeCls<int>
不需要
void UseT(T t)
方法似乎是错误的。我确定我在这里缺少专业知识(我不是C ++专家)。有人可以启发我吗?     

解决方法

        专业化可以按照您认为合适的任何方式进行专业化。如果要忽略所有方法,则添加或删除基类,添加或删除数据成员,然后就可以了。
template <class T>
class Foo {};

template <>
class Foo<int> { void extrafunc(); }; //fine

template <>
class Foo<bool> : public ExtraBase {}; // fine

template <>
class Foo<double> { int extradata; }; // fine
当使函数专用化时,唯一的限制是参数保持不变(相对于主模板),尽管您可以重载自己的内心。
template <class T>
void foo(const T&);

template <>
void foo<int>(int); // not fine,must be const int&

void foo(int); // fine,this is an overload,not a specialisation

template <class T>
void foo(T*); // fine,again this is an overload,not a specialisation
    ,        因为ѭ5与ѭ6或其他other7完全不同。它们没有任何关系,因此可以拥有所需的任何成员。只是要确保不要调用
i.UseT()
,这当然是编译器开始抱怨的地方。     ,        您的代码永远不会调用UseT的“ 9”版本,因此您无需提供它。     ,           我已将答案标记为“正确”,   但我不是很满意。我不是   询问它如何工作;我在问为什么   是这样设计的。它的方式   工作并不能使我感到一致   与OO。它甚至看起来是一致的。   为什么功能模板   专业化有限制   接口必须一致,   而课程模板专业化   才不是?? 如果这是您的问题,那么您可能首先应该这样说。 我将从最后一点开始:为什么函数需要相同的签名。那些简单的函数已经可以通过重载来重用名称。
int f(int);
double f(double); //no templates needed
允许专业化更改功能的签名将不必要地使本来就很困难的名称解析过程复杂化,而无需实际提供任何其他功能。 对于类类型,模板要复杂得多。您不仅需要考虑成员函数,还拥有成员对象,typedef,嵌套类型等。专业化专长于所有这些。如果
SomeTemplatedObject<double>
要求通常不是
SomeTemplatedObject<T>
的特定私人成员,那么如何在不更改\“ interface \”的情况下将
SomeTemplatedObject
专门化为
double
?还是对于某些类型没有意义的方法呢​​?还是需要修改嵌套类型以保持一致的接口?而且,这甚至还没有涉及到模板元编程的更大问题。 一般情况下,您甚至不需要具有完整的类型。
template<typename T>
struct Object;

template<>
struct Object<int> { //what interface does this need?
  typedef int type;
};
如果您不得不遵循OO的一些纯粹的定义,那么您总是可以随意不对模板进行专门化而不必精确匹配其原始布局。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...