以下代码由于char
的隐式转换而编译。我不确定为什么,因为我期望(并期望失败)的唯一隐式转换是从char const*
到size_t
。
#include <cstddef>
struct foo
{
int operator[](size_t i) const { return 1; }
operator char() const { return 'a'; }
};
int main()
{
foo f;
f["hello"]; // compilation error desired here
}
这里允许编译的隐式转换是什么?如果我删除operator char
或将其explicit
删除,则编译会在所需位置失败。
从中提取此代码的类确实需要隐式转换和operator[]
。那么有没有一种方法可以在不明确转换的情况下阻止行为?
答案 0 :(得分:34)
行编译的原因是,通过隐式转换,它可以重新解释为'a'["hello"];
,而*(('a')+("hello"));
又与编写struct foo
{
operator char() const { return 'a'; }
int operator[](size_t i) const { return 1; }
// prevent accidental use of foo["hello"]
int operator[](char const*) const = delete;
};
同样编译。
标准摘录:
5.2.1订阅:
...... 表达E1 [E2]与*((E1)+(E2))...
相同(根据定义)
不使转换运算符显式化的最简单的解决方法是将违规的下标运算符声明为已删除:
{{1}}
答案 1 :(得分:0)
f["hello"];
转换为f.operator [](index),其中index是指向“hello”的指针的值。在您的情况下,它调用operator [](size_t i)。因此,绝对可以,编译器不会抱怨。实际上索引值将是l; arge值(指针的值),因此在重载[]时要小心,并检查上边界 事实上,如果你有:
char *c = "hello"; // c is a pointer
f[c]; // ok