C ++类型强制演绎

时间:2014-05-29 16:38:13

标签: c++

我正在玩Colvin-Gibbons在C ++ 03中实现移动语义的技巧,我得到了以下内容:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

template <typename T>
class buffer {
    struct buffer_ref {
        buffer_ref(T* data) : data_(data) {}
        T* data_;
    };

public:
    buffer() : data_(NULL) {}
    //explicit buffer(T* data) : data_(data)        {}
    buffer(size_t size)      : data_(new T[size]) {}
    buffer(buffer_ref other) : data_(other.data_) { other.data_ = NULL; } 
    buffer(buffer    &other) : data_(other.data_) { other.data_ = NULL; }
   ~buffer()                                      { delete [] data_;    }

    operator buffer_ref() { buffer_ref ref(data_); data_ = NULL; return ref; }
    operator T*()         { return data_;                                    }

private:
    T* data_;
};


int main() {
    buffer<float> data(buffer<float>(128));
    printf("ptr: %p\n", (float*)data);

}   

修改:格式化

我希望能够在方便的时候使用我的缓冲区作为指向基类型的指针,所以我在指针类型中添加了一个转换操作符,它可以正常工作。但是,如果我取消注释带有指针的构造函数,那么转换推导会混淆并抱怨模糊转换(因为它可以转到缓冲区 - > T * - &gt;缓冲区或缓冲区 - &gt; buffer_ref-&gt;缓冲区) 。我希望指针构造函数上有一个显式修饰符来修复它,但事实并非如此。能理解C ++转换演绎的人比我更能解释编译器的想法吗?

1 个答案:

答案 0 :(得分:2)

这是13.3.1.3 [over.match.ctor] 的直接结果:

  

当类类型的对象被直接初始化(8.5),或者从相同或派生类类型(8.5)的表达式中复制初始化时,重载决策选择构造函数。对于直接初始化,候选函数是正在初始化的对象的类的所有构造函数。对于复制初始化,候选函数是该类的所有转换构造函数(12.3.1)。 [...]

由于buffer<float> data(buffer<float>(128));是直接初始化,因此您明确要求考虑explicit构造函数。

如果你写:

buffer<float> data = buffer<float>(128);

然后没有歧义。