std::编译时继承的条件,与编译时方法的std::enable_if配对



我想设计一个有两个参数的模板类,在编译时基于模板参数继承两个互斥基类中的一个。我想让它对我来说简单,所以想出了这个工作示例。根据模板参数得到了std::conditional的继承条件。我用std::enable_if设置了用于条件继承的专用方法。

class Empty {};
template<typename T>
class NonEmpty { protected: std::vector<T> mObjects; };
template< typename A, typename B = A>
class Storage : public std::conditional<std::is_same<A, B>::value, Empty, NonEmpty<B>>::type
{
public:
template<typename C = B, typename std::enable_if<std::is_same<C, A>::value>::type* = nullptr>
void doStuff()
{ 
// one argument or two arguments with same type 
// do stuff ...
};
template<typename C = B, typename std::enable_if<std::is_same<C, A>::value>::type* = nullptr>
void doSomthingElse()
{ 
// one argument or two arguments with same type 
// do something exclusively just for this argument constellation  ...
};

template<typename C = B, typename std::enable_if<!std::is_same<C, A>::value>::type* = nullptr>
void doStuff()
{ 
// two arguments with different types
// do stuff with inherited variables of NonEmpty-Class ...
};
};
int main()
{
EmptyClass<int> emp;
NonEmptyClass<int, float> nonemp;
emp.doStuff();
emp.doSomethingElse();
nonemp.doStuff();
}

是否有更好的方法去做,或者对我现有的解决方案有任何改进?(我使用GCC 8.1.0和c++ 14)

在我看来,部分专门化模板会更好,因为两个版本的整个实现是完全独立的。这样你也可以不继承任何类,而不是继承一个空类。

template<typename T>
class NonEmpty {
protected:
std::vector<T> mObjects;
};
template<typename A, typename B = A>
class Storage : public NonEmpty<B>
{
public:
void doStuff()
{
std::cout << "doStuff() different typesn";
};
};
template<typename A>
class Storage<A, A>
{
public:
void doStuff()
{
std::cout << "doStuff() same typesn";
};
void doSomethingElse()
{
std::cout << "doSomethingElse()n";
};
};
int main() {
Storage<int> emp;
Storage<int, float> nonemp;
emp.doStuff();
emp.doSomethingElse();
nonemp.doStuff();
}

我看不出把它们都放在一个模板中有什么好处。我的印象是,你把所有的东西都塞在一个单一的模板,但需要选择哪个版本,它是为每个单一的方法,使事情变得复杂。两个独立的类:

template <typename A>
struct inherits_from_empty : Empty {
// implement methods here, no sfinae needed
};

template <typename A, typename B>
struct inherits_from_nonEmpty : NonEmpty<A> {
// implement methods here, no sfinae needed
};

可从via

选择
template <typename A,typename B>
using Storage = std::conditional_t<std::is_same<A, B>::value,
inherits_from_empty<A>,
inherits_from_nonEmpty<A>>;

最新更新