这样的事情刚刚出现在另一个问题中,引起了我的兴趣。鉴于Foo
被声明为:
struct Foo
{
static void bar() {std::cout << "Bar!";}
};
做这样的事似乎工作得很好:
std::vector<Foo> v;
v[10].bar();
但是,这种用法实际上是合法的吗?如果bar()
未声明static
,该怎么办?
答案 0 :(得分:9)
做这样的事似乎工作得很好:
这并不意味着它没问题。
请阅读与罗杰米勒有很好类比的http://c-faq.com/ansi/experiment.html:
&#34;有人告诉我,在篮球比赛中,你无法控球并跑动。我得到了一个篮球并尝试了它,它运作得很好。他显然不懂篮球。&#34;
访问v[10]
是未定义的行为。如果你在其上调用成员函数并不重要,即使只是访问v[10]
是未定义的。 (正如评论中所指出的,即使在调用静态成员函数时也会评估对象表达式,恕我直言应该是显而易见的,因为v[10]
未在未评估的上下文中使用,如sizeof(v[10])
或{{ 1}})。
你不能用视图编写C ++代码&#34;这似乎工作得很好&#34;并假设这意味着程序是正确的。
答案 1 :(得分:4)
根据[class.static]/1(强调我的):
可以使用qualified-id引用类X的静态成员 表达式X :: s;没有必要使用类成员访问 用于引用静态成员的语法。 可以参考静态成员 使用类成员访问语法,在这种情况下使用对象 评估表达。
v[10]
必须进行评估,bar
是否静态无关紧要。该向量肯定会超出界限,因此它肯定是未定义的行为。
答案 2 :(得分:-3)
函数“bar”的声明都可以,两者都是合法的。 当您打算在不同文件中使用“bar”函数时,唯一的区别就出现了。 void bar()具有全局范围,意味着您可以在任何文件中使用它(存在“bar”以外的文件)
但是static void bar()将具有文件范围,这意味着您仍然可以在父文件中使用它,但不能在该文件之外使用它。
否则,两者都是正确的。