C++ 简单继承——奇怪的编译器错误

C++ 简单继承——奇怪的编译器错误,c++,c++11,gcc,C++,C++11,Gcc,我有一段简单的代码,它包装了struct timespec,并为其最小值和最大值添加了静态成员 #include <sys/stat.h> #include <limits> struct Timespec : public timespec { Timespec() :timespec() {}; Timespec(decltype(tv_sec) s, decltype(tv_nsec) ns

我有一段简单的代码,它包装了
struct timespec
,并为其最小值和最大值添加了静态成员

#include <sys/stat.h>
#include <limits>
struct Timespec : public timespec {
    Timespec() :timespec() {};
    Timespec(decltype(tv_sec) s, 
                     decltype(tv_nsec) ns
            ) {
        tv_sec = s;
        tv_nsec = ns;
    }
    static const Timespec max;
    static const Timespec min;
};

const Timespec Timespec::min  = Timespec(0,0);
const Timespec Timespec::max  = Timespec(
        std::numeric_limits<decltype((timespec().tv_sec))>::max(), 
        std::numeric_limits<decltype((timespec().tv_nsec))>::max()
    );
它应该这样做吗?

decltype(未授权的类成员访问)返回所引用实体的声明类型

decltype((类成员访问))
返回不同的内容。如果类成员访问表达式的类型为
T
,则如果表达式是左值,则返回的类型为
T&
;如果表达式是xvalue,则返回的类型为
T&
;如果表达式是prvalue,则返回的类型为
T

之前,如果
E2
命名了非引用类型的非静态数据成员,则
E1.E2
E1
具有相同的值类别。因此给定
struct A{double x;}
decltype(A().x)
decltype((A().x))
都是
double
A()
是一个PR值)

在CWG 616之后,
E1.E2
现在是一个左值,如果
E1
是一个左值,则是一个xvalue(同样,当
E2
命名非引用类型的非静态数据成员时)。所以
decltype(A().x)
应该是
double
decltype((A().x))
应该是
double&

由于CWG 616是一份缺陷报告,因此追溯适用;您的原始代码不应在符合要求的编译器中编译


您观察到的实际行为似乎是编译器错误。即使它没有实现CWG 616的分辨率,该标准的任何修订版都不允许它区分
timespec().tv\u nsec
timespec().tv\u nsec
,或者进行
decltype((timespec().tv\u nsec))
返回左值引用。

请显示出现错误的实际代码。您可能希望使用
std::remove\u reference\t
。删除额外的括号。报告:。Clang在这里的行为至少是一致的,这表明他们还没有执行CWG616的决议。正确,Clang还没有
$ make timespec.o
g++ -std=c++0x   -c -o timespec.o timespec.cc
In file included from timespec.cc:2:0:
/usr/include/c++/4.8/limits: In instantiation of ‘static constexpr _Tp std::numeric_limits<_Tp>::max() [with _Tp = long int&]’:
timespec.cc:18:55:   required from here
/usr/include/c++/4.8/limits:313:48: error: value-initialization of reference type ‘long int&’
       max() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
                                                ^
/usr/include/c++/4.8/limits:313:51: error: body of constexpr function ‘static constexpr _Tp std::numeric_limits<_Tp>::max() [with _Tp = long int&]’ not a return-statement
       max() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
                                               ^