当前,我正在使用如下所示的代码。
template<class T, class U = char>
struct ScoredObject {
ScoredObject( T *object, double score, const U &data = U() ) noexcept( noexcept( U( data ) ) ) : object( object ), score( score ), data( data ) {}
T *object;
double score;
U data;
// ...
};
在所有情况下,除1外,不使用data
变量。默认为char
,以便尽可能少地浪费空间。实际上,我希望它是void
,但当然它不会编译。
我知道我可以在构造函数上执行一些std::enable_if
,但是问题仍然是data
变量。当data
为U
时,是否可以使用某种模板“魔术”来删除void
变量?
基本上,我想做这样的事情(我知道这是无效的)
template<typename f = U, typename std::enable_if<!std::is_void<f>::value, bool>::type = true>
U data;
答案 0 :(得分:1)
您可以根据Scored_object
的类型从不同的基础继承U
。像这样:
template<class T, class U>
struct Scored_object_base : Scored_object_base<T, void> {
U data;
using Base = Scored_object_base<T, void>;
Scored_object_base(T* object, double score, const U& data)
: Base(object, score), data(data) {}
};
template<class T>
struct Scored_object_base<T, void> {
T* object;
double score;
Scored_object_base(T* object, double score)
: object(object), score(score) {}
};
template<class T, class U = void>
struct Scored_object : Scored_object_base<T, U> {
using Base = Scored_object_base<T, U>;
using Base::Base;
};
template<class T, class U>
bool operator==(const Scored_object<T, U>& o1, const Scored_object<T, U>& o2) {
const auto f = (*o1.object == *o2.object && o1.score == o2.score);
if constexpr (std::is_void_v<U>)
return f;
else
return f && o1.data == o2.data;
}
int main() {
int i;
Scored_object<int, void> o1(&i, 1);
Scored_object<int, char> o2(&i, 1, 'a');
std::cout << sizeof(o1) << std::endl; // Output: 16
std::cout << sizeof(o2) << std::endl; // Output: 24
}