因此,我尝试使用空基优化创建一个压缩对。我希望这样,如果类a和b是空的,那么compressed_pair<a, b>也是空的。所以我定义了我的压缩对,如下所示:
template <class First, class Second>
struct compressed_pair : First, Second
{
compressed_pair() {}
compressed_pair(const First& x, const Second & y)
: First(x), Second(y)
{}
First& first() { return *this; }
Second& second() { return *this; }
};但是,如果其中一种类型继承自另一种类型,则会变得不明确。例如,当我编译这个程序时:
struct a
{};
struct b : a
{};
int main()
{
compressed_pair<a, b> p;
auto x = p.first();
}我从clang得到了这个错误:
compressed_pair.cpp:8:30: error: ambiguous conversion from derived class 'compressed_pair<a, b>' to base class 'a':
struct compressed_pair<struct a, struct b> -> struct a
struct compressed_pair<struct a, struct b> -> struct b -> struct a
First& first() { return *this; }
^~~~~
compressed_pair.cpp:21:16: note: in instantiation of member function 'compressed_pair<a, b>::first' requested here
auto x = p.first();
^那么,如何避免模棱两可的转换,使compressed_pair<a, b>仍然是空的呢?
发布于 2015-03-01 05:27:29
您所遇到的问题是,从compressed_pair中可以应用转换的两个基础。您需要能够驱动编译器选择其中之一。想到的第一件事是添加另一层继承,您可以将其用作选择器:
template <int N, typename T>
struct element : T {};
template <typename T, typename U>
struct compressed_pair : element<0, T>, element<1, U> { ... };那么访问器的实现可以是:
template <typename T, typename U>
T& compressed_pair<T,U>::first() {
return static_cast<element<0,T>&>(*this);
}访问器内部的强制转换强制选择两个直接基( element<0,T> )中的一个。从那时起,只有一个T类型的基。
您还可以使用将访问器移动到该中间步骤,而不是将其设置为完整类型。最后,通过专门化,您应该能够为element提供一个支持非类类型的不同实现,因为当前的实现会阻塞int这样的类型。
https://stackoverflow.com/questions/28788715
复制相似问题