优先考虑课程专业化

时间:2014-11-10 10:27:08

标签: c++ c++11

假设我们有一个双参数化模板,如

template<class A, class B>
class Class { .... };

并且特定A和特定B

有特化
template<class B> class Class<A1,B> { .... };
template<class A> class Class<A,B1> { .... };

现在,当我必须实例化Class<A1,B1>时,编译器会抱怨模糊,因为它发现<A,B1><A1,B>同样可用。

当然可以通过添加<A1,B1>专精来消除问题,但在我的背景下 - 它将是相同的<A1,B>

有没有办法消除歧义而不重复整个<A1,B>完整代码?

3 个答案:

答案 0 :(得分:12)

一种可能性是简单地禁止选择第二个专业化:

template<class A, class B, class=void>
class Class {};

template<class B>
class Class<A1,B> {};

template<class A>
class Class<A, B1, typename std::enable_if<!std::is_same<A,A1>::value>::type> {};

Demo

答案 1 :(得分:6)

我将第三个默认参数添加到基本模板,并允许通过SFINAE获取每个专业化:

template<class A, class B, 
         class extra = void /* Enable/disable specialization through SFINAE */>
class Class { public: void hello() {std::cout << "Base" << std::endl;} };

template<class B> class Class<A1, B> { 
 public: 
 void hello() {std::cout << "First" << std::endl;} 
};
template<class A> class Class<A, B1, 
                   typename std::enable_if<!std::is_same<A, A1>::value>::type> {
  public: 
  void hello() {std::cout << "Second" << std::endl;} 
};

int main()
{     
  Class<A1,B1> obj;// The first one is picked up
  obj.hello();
  Class<A,B1> obj2; // The second one is picked up
  obj2.hello();
  Class<A,B> obj3; // Base
  obj3.hello();
}

Example

甚至更简单(取决于您的用例是否可以接受):

template<class A, class B, bool AisA1 = std::is_same<A,A1>::value>
class Class { public: void hello() {std::cout << "Base" << std::endl;} };

template<class B> class Class<A1, B, true /* Pick this when A == A1 */> { 
 public: void hello() {std::cout << "First" << std::endl;} 
};
template<class A> class Class<A, B1, false> { 
 public: void hello() {std::cout << "Second" << std::endl;} 
};

Example

答案 2 :(得分:0)

免责声明:我没有测试过,我也不是模板专家。

我的想法:给这个重复的专业化命名,所以你可以参考它:

template<class B> classA1 { ... }; // code goes here.

template<class B> class Class<A1,B> : public classA1<B> {};
template<> Class<A1,B1> : public classA1<B1> {};