此代码适用于GCC,但不适用于clang。
class Base
{
static constexpr int PRIVATE = 1;
};
struct Derived : public Base
{
template <class T>
int bar( T & t )
{
return PRIVATE;
}
};
int main()
{
Derived d;
int i = 3;
d.bar(i);
}
Godbolt链接:https://godbolt.org/g/qPJ47p
在私有成员函数的情况下,如果实例化模板函数,GCC会正确检测访问私有成员的尝试,否则不会。即使从未实例化模板函数,Clang也会检测到该尝试。
但是,当使用私有静态constexpr变量时,即使模板函数被实例化,GCC(最新的8.1)也无法停止私有访问。 Clang正确(?)抱怨。
问题:在这种情况下,两个编译器中哪一个符合标准?
在我看来,GCC在允许访问私有静态constexpr变量方面是不对的。然而与此同时,它似乎并不是一个过于复杂的问题,但它并不是最新的海湾合作委员会:这似乎是故意的。
非常感谢paxdiablo明确而彻底的回答。根据他的建议,我已经提供了一个更全面的测试用例列表,并将其缩小到导致GCC问题的static
说明符。有关更多详细信息,请参阅此Godbolt链接:https://godbolt.org/g/A3zCLk
Comparison of GCC and Clang:
Private member | GCC | Clang
static const | accept | reject
static constexpr | accept | reject
static | accept | reject
const | instantiate | reject
no-specifiers | instantiate | reject
static function | instantiate | reject
function | instantiate | reject
("instantiate" means GCC rejects it upon template instantiation)
答案 0 :(得分:7)
这个肯定看起来像一个bug,因为它是一个实例化的模板函数还是一个真正的函数应该对基类中的私有成员的可访问性没有影响。如果您将代码更改为:
int bar(int&) {
return PRIVATE;
}
然后它正确地抱怨:
testprog.cpp: In member function 'int Derived::bar(int&)':
testprog.cpp:3:26: error: 'constexpr const int Base::PRIVATE' is private
static constexpr int PRIVATE = 1;
^
testprog.cpp:9:16: error: within this context
return PRIVATE;
^
我只会在gcc
上raise this as a bug。如果他们做对其有效性有不同的看法,他们会让你知道。
而且,当你做提交错误时,我建议使用有效的绝对极简主义示例,它会使它们更容易调试。我把它归结为:
class Base {
static constexpr int PRIVATE = 42;
};
struct Derived : public Base {
template <class T> int bar(T) {
return PRIVATE;
}
};
int main() {
Derived d;
return d.bar(1);
}
您可能还想指出声明PRIVATE
的各种可能性及其对gcc
和clang
的影响(截至此问题的中继线):
gcc clang
-------- --------
static constexpr int accepted rejected
static const int accepted rejected
const int rejected rejected
int rejected rejected
使用非模板化函数(如上所述):
int bar(int) {
return PRIVATE;
}
似乎导致gcc
&#34;行为&#34;本身:
gcc clang
-------- --------
static constexpr int rejected rejected
static const int rejected rejected
const int rejected rejected
int rejected rejected
因此,如果确实出现gcc
问题,我会认为static
与模板之间存在一些互动这个问题。
答案 1 :(得分:0)
道歉,这不是答案,而是一个相关问题:
db2
derby
h2
hsqldb
mysql
oracle
postgresql
sqlite
sqlserver
sybase
我还没有找到错误号。