繁体   English   中英

为什么未完成此用户定义的转换?

[英]Why is this user-defined conversion not done?

考虑:

template<typename T>
struct Prop
{
    T value;
    operator T() { return value; }
};

int main()
{
    Prop<float> p1 { 5 };
    Prop<std::vector<float>> p2 { { 1, 2, 3 } };

    float f1 = p1;              // Works fine
    float f2_1_1 = p2.value[0]; // Works fine
    float f2_1_2 = p2[0];       // Doesn't compile

    return 0;
}

为什么标记为这样的行不能编译? 它不应该使用提供的转换运算符执行隐式转换为std::vector<> ,以便可以找到[]吗?

该网站上还有(许多)其他问题,要求对此问题有所不同,但我找不到我认为适用于此的问题。 它与std::vector是模板有关吗?

成员函数调用的对象(包括下标运算符重载)不考虑隐式转换。

请考虑是否允许这样做的后果:每次像这样调用任何未声明的成员函数时,编译器都必须弄清楚该对象可以转换为的所有类型(请注意,其他任何其他不相关的类型都可以具有转换构造函数),并检查是否已声明缺少成员函数。 更不用说这会对代码阅读器造成多大的混乱(在您的转换运算符情况下,转换可能很明显,但在转换构造函数的情况下却不明显,据我所知,它们在其他方面没有不同的对待)。

那么有没有一种符号上方便的方法可以使Prop表现出我想要的方式

您必须为要透明传递的vector的每个成员函数定义一个成员函数。 下面是下标运算符的示例:

auto operator[](std::size_t pos) {
    return value[pos];
}
auto operator[](std::size_t pos) const {
    return value[pos];
}

问题当然是必须明确声明所有包装的成员函数。 另一个问题是类型取决于T参数。 例如, vector::operator[]使用vector::size_type ,可能没有为您可能使用的所有T定义(肯定不是为float )。 在这里,我们做出妥协,并使用std::size_t

创建这种“透明”包装的一种较省力的方法是继承。 一个公共继承的模板将自动具有父对象的所有成员函数,并且可以隐式转换为它,并且可以由父类型的指针和引用来引用。 但是,这种方法的透明度有点问题,主要是因为~vector不是虚拟的。

私有继承允许与您的成员方法相同的包装,但是语法好得多:

template<typename T>
struct Prop : private T
{
    using T::operator[];
    using T::T;
};

请注意,继承方法阻止您将基本类型用作T 另外,它使隐式转换成为不可能(即使使用转换运算符也是如此),因此您不能在期望T自由函数中将Prop用作T


PS。 请注意,转换运算符返回一个值,因此必须复制向量,这可能是不希望的。 考虑改为提供参考版本:

operator T&&()&&           { return *this; }
operator T&()&             { return *this; }
operator const T&() const& { return *this; }

与任何

p2.size();
p2.begin();
p2.push_back(24);
// etc.

编译没有意义

p2[0];

相当于

p2.operator[](0);

编译没有意义\\


如果您想要这种行为(即让Prop<T> 借用 T成员),则Bjarne提出了C ++提议,将点运算符添加到语言中。 我将以与operator- ->用于智能指针的方式相同的方式工作。 事发时有很多争议,所以我不会为此屏住呼吸。

运营商点建议的背景知识-Bjarne Stroustrup

操作员点(R3​​)-Bjarne Stroustrup,Gabriel Dos Rei

通过委派进行智能引用:N4477运营商点的替代选择-Hubert Tong,费萨尔·瓦利(Faisal Vali)

运算符点的替代方法-Bjarne Stroustrup

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM