c++ - 使用压缩对进行不明确的基类转换

标签 c++ c++11

所以我尝试使用 empty base optimization 创建一个压缩对.我希望这样,如果类 ab那么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>是空的吗?

最佳答案

您遇到的问题是来自 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 这样的类型.

关于c++ - 使用压缩对进行不明确的基类转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28788715/

相关文章:

c++ - float 的设置精度

c++11 - 基于 C++ 中可能输入的最大范围推导返回类型

c++ - 我可以定义一个指向 std::function 类型对象的函数指针吗?

c++ - (C++) 为什么 '||' 逻辑运算符返回 1?

java - JNI 错误 : Local reference table overflow 512 entries

c++ - 从 ListView 中选择并突出显示项目

C++11 非类型模板参数捆绑扩展

c++ - 完美转发一个参数包: convert args without expansion?

c++ - omn​​et 中对 ISO c++ 2011 标准的库支持

c++ - 局部静态变量初始化是线程安全的