C++意外的implict转换

mar*_*ack 30 c++ casting

以下代码由于隐式转换而编译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
}
Run Code Online (Sandbox Code Playgroud)

什么是允许这个编译的隐式转换?如果我删除operator char或制作它,explicit则编译在所需位置失败.

提取此代码的类确实需要隐式转换和operator[].那么有没有一种方法可以防止行为而不使转换明确?

imr*_*eal 34

行编译的原因是,通过隐式转换,它可以被重新解释为'a'["hello"];,而后者又与写入*(('a')+("hello"));也编译相同.

摘录标准:

5.2.1订阅:

......表达式E1 [E2]与*((E1)+(E2))相同(根据定义)......

在不使转换运算符显式化的情况下,最简单的解决方法是将违规的下标运算符声明为已删除:

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;
};
Run Code Online (Sandbox Code Playgroud)

  • @UlrichEckhardt,是的,"你好"[0]`相当于`0 ["你好"]. (7认同)
  • 实际上,这并不明显.这是C++.有些书充满了C++陷阱和陷阱. (4认同)
  • @Jerry101:_some_书籍甚至故意包括它们! (4认同)
  • ...和通过相当于"*(E2 + E1)"和"E2 [E1]"的交换性?我不会说那么明显...... (3认同)