我有一个模板类(我无法修改),我们称之为SomeClass
,我想专门针对仅来自特定类的类。关注this answer我能够在gcc 6.3.1中执行此操作,但不幸的是我需要在gcc 4.9.2中执行此操作,并且在编译时它失败了“partial specialization SomeClass<T>
没有专门化任何模板参数“。
有什么方法可以改变下面的内容,使其与gcc 4.9.2一起使用?
#include <iostream>
#include <string>
using namespace std;
struct A {
string name() { return "A"; }
};
struct B : A {
string name() { return "B"; }
};
struct C {
string name() { return "C"; }
};
template<typename T, typename = std::enable_if_t<std::is_base_of<A, T>::value>>
using enable_if_a = T;
template<typename T>
struct SomeClass {
using Type = T;
};
template<typename T>
struct SomeClass<enable_if_a<T>>
{
using Type = A;
};
int main(int, char**)
{
SomeClass<A>::Type el1;
SomeClass<B>::Type el2;
SomeClass<C>::Type el3;
cout << el1.name() << "," << el2.name() << "," << el3.name() << endl;
}
输出:
A,A,C
答案 0 :(得分:3)
有点做作,但这是一个至少有效的机器
基本的想法是隐藏 A
并且不直接从它继承。相反,您可以严重依赖mixins并在探测器中组合几个类,您可以使用这些类专门SomeClass
。
缺点是像B
这样的课程变得更加深奥,我不确定它在一天结束时是否值得。直接专业化可能更好。
话虽如此,这是一个有效的例子:
#include <iostream>
#include <string>
#include <utility>
using namespace std;
class ADerivedFactory {
struct A {
string name() { return "A"; }
};
template<typename T>
struct Detector: T { using type = A; };
public:
template<template<typename> class C>
using type = Detector<C<A>>;
};
template<typename T>
struct AT : T {};
template<typename T>
struct BT : T {
string name() { return "B"; }
};
using A = ADerivedFactory::type<AT>;
using B = ADerivedFactory::type<BT>;
struct C {
string name() { return "C"; }
};
template<typename T>
struct SomeClass {
using Type = T;
};
template<template<typename> class C>
struct SomeClass<ADerivedFactory::type<C>>
{
using Type = typename ADerivedFactory::type<C>::type;
};
int main(int, char**)
{
SomeClass<A>::Type el1;
SomeClass<B>::Type el2;
SomeClass<C>::Type el3;
cout << el1.name() << "," << el2.name() << "," << el3.name() << endl;
}
在wandbox上查看并运行。