C++ 专门化派生类中的模板成员

C++ 专门化派生类中的模板成员,c++,templates,C++,Templates,我有一个带有模板成员的基类,它在某些情况下是显式专门化的。派生类进一步专门化基类的模板成员。除此之外的理由是,模板成员的各种专门化在“逻辑上”执行相同的工作,以适应特定情况。基类提供一些模板专门化,这些模板专门化在某些情况下执行任务,派生类应通过进一步专门化模板成员将相同的任务“扩展”到其他情况 这里有一个简单的例子来说明我遇到的问题 #include <iostream> struct A { template <int i> void dosomething

我有一个带有模板成员的基类,它在某些情况下是显式专门化的。派生类进一步专门化基类的模板成员。除此之外的理由是,模板成员的各种专门化在“逻辑上”执行相同的工作,以适应特定情况。基类提供一些模板专门化,这些模板专门化在某些情况下执行任务,派生类应通过进一步专门化模板成员将相同的任务“扩展”到其他情况

这里有一个简单的例子来说明我遇到的问题

#include <iostream>

struct A {
  template <int i>
  void dosomething();

  void show();
};

template<>
void A::dosomething<0>()
{
  std::cout << "0 in A" << std::endl;
}

void A::show()
{
  dosomething<0>();
}

struct B : A {
  // Without the following declaration:
  // error: template-id ‘dosomething<1>’ for ‘void B::dosomething()’
  // does not match any template declaration
  template <int i>
  void dosomething();
};

template<>
void B::dosomething<1>()
{
  std::cout << "1 in B" << std::endl;
}

int main()
{
  A x;
  x.dosomething<0>();

  B y;
  y.dosomething<0>(); // Link error!
  y.show();
  y.dosomething<1>();

  return 0;
}
B
的定义中,代码未编译,错误如下:

template-id ‘dosomething<1>’ for ‘void B::dosomething()’
does not match any template declaration.

该错误是由于main中的调用
y.dosomething()
引起的。它可以通过调用
y.A::dosomething()
来避免。为什么
dosomething()
B
的实例中明显不可见?

当您对成员函数进行
越界定义时,该函数的声明将在
操作符前面引用的类中查找

考虑这一点:

struct C { void test(); };
struct D : C { };

void D::test() { }; // error, test is not a member of D but of C
这和做同样的事

template<> void B::dosomething<1>() 
{ }
模板无效B::dosomething()
{ }
dosomething
和所有it专业化定义必须由声明它的类限定,即在
A
中,就像您对
dosomething
所做的那样

还要注意,
B
中的
dosomething
声明与
A
的声明完全无关。由于调用了未定义的专门化
B::dosomething
,因此出现链接错误


您可以创建专门化
模板void A::dosomething(){}
,但是您没有得到您期望的多态行为,
A::dosomething
将由所有派生类共享,如果您确实需要子类的不同版本的
dosomething
,则仅限于初始重复,为了从
B
访问
A::dosomething
,您可以按
static\u cast

进行操作,谢谢您的回答。但我仍然感到困惑的是,
B
显然没有看到
A
的模板声明,因此我无法进一步专门化模板函数
A::dosomething
@francesco I编辑答案以提供更多说明,如果还有其他需要澄清的地方,请告诉我。关于澄清和链接,我们有很多。
struct C { void test(); };
struct D : C { };

void D::test() { }; // error, test is not a member of D but of C
template<> void B::dosomething<1>() 
{ }