c++ - 简单的继承——奇怪的编译错误

标签 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
            ) {
        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((timespec()/*...*/ 替换为 decltype((Timespec()/*...*/ 最后两行,我得到:

$ 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(); }
                                               ^

它应该这样做吗?

最佳答案

decltype(unparenthesized class member access) 返回所引用实体的声明类型。

decltype((class member access)) 返回不同的东西。如果类成员访问表达式的类型是T,那么返回的类型是T&如果表达式是左值,T&&如果表达式是一个 xvalue,如果表达式是一个 prvalue,则为 T

之前CWG 616 ,如果 E2 命名了一个非引用类型的非静态数据成员,那么 E1.E2E1 具有相同的值类别。所以给定 struct A { double x; };decltype(A().x)decltype((A().x)) 都是double (A() 是纯右值)。

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

由于 CWG 616 是一份缺陷报告,因此它具有追溯力;您的原始代码不应在符合标准的编译器中编译。

您观察到的实际行为似乎是一个编译器错误。即使它没有实现 CWG 616 的决议,标准的任何修订版也没有任何内容允许它区分 timespec().tv_nsecTimespec().tv_nsec,或者让 decltype((timespec().tv_nsec)) 返回一个左值引用。

关于c++ - 简单的继承——奇怪的编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32661665/

相关文章:

c++ - 为什么允许 dynamic_cast 到非唯一基类类型?

c++ - 错误 C2280 : 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function

c++ - 在编译时使用 gnu++11 过滤值列表,不使用 stdlib(Arduino 环境)

c++ - 什么 CMake 变量用于在 XCode 中设置 C++ 标准库?

c++ - mingw-w64 : slow sprintf in <cstdio>

c++ - Visual Studio 2013中的POSIX header (来自MinGW项目)

c++ - session 之间未正确恢复 CMFCToolbar 布局

c++ - 结构错误 : Request for member

c - gcc -Ofast -pg 的 gprof 结果错误

c++ - boost::bind 如何调用私有(private)方法?