当前位置: 首页 > 知识库问答 >
问题:

获取嵌套在类模板中的结构的“sizeof”非静态成员是非法的吗?

寿翰飞
2023-03-14

在clang/llvm 3.6.2中,以下代码在使用std=c 11编译时导致编译错误:

template <typename T=void>
class bar
{
public:
    struct foo
    {
        int array[10];
    };

    int baz()
    {
        return sizeof(foo::array);
    }
};

int main(void)
{
    bar<> b;
    return b.baz();
}

命令行调用:

$ clang++ -std=c++11 nonstatic.cpp -o nonstatic
nonstatic.cpp:12:28: error: invalid use of non-static data member 'array'
        return sizeof(foo::array);
                      ~~~~~^~~~~
nonstatic.cpp:20:14: note: in instantiation of member function
'bar<void>::baz' requested here
    return b.baz();

如果我将更改为不再是模板,如

class bar
{
public:
    struct foo
    {
        int array[10];
    };

    int baz()
    {
        return sizeof(foo::array);
    }
};

int main(void)
{
    bar b;
    return b.baz();
}

然后代码干净地编译。值得注意的是,GCC 5.2.1 在 std=c 11 下接受这两个版本。同样值得注意的是,将数组移动到封闭的类模板正文中(但将其保留为模板)也会导致 clang 接受这一点。

相对于标准,哪种行为是正确的?这是GCC中的bug,clang,还是两者都有?

(我在cfe用户上问了同样的问题,但到目前为止没有收到任何回复)。

共有1个答案

汝才良
2023-03-14

这当然是一个大错误;< code>sizeof表达式的操作数是表示非静态数据成员的id表达式,因此[expr.prim.general]/13成立。下面是一个简化的例子:

template<class T> struct M { int f() { return sizeof(T::x); } };
struct S { int x; };
int main() { return M<S>{}.f(); }

当在模板实例方法中的未计算上下文中访问依赖类型成员时,就会出现此错误。Clang实现了n2253规则,允许在未评估的上下文中使用非静态数据成员(以及后来的改进),这看起来相当脆弱,并且与模板交互不好;一个类似的(尽管不同)错误正在出现http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20151019/141535.html.

我找不到任何迹象表明这已经报告给Clang Bugzilla;您可能想要打开一个新错误。

根据您的情况,变通方法可能包括将静态类型和值计算移到实例方法之外;值得注意的是,即使将baz设为静态成员函数,也足以说服clang接受您的代码。

 类似资料:
  • 我有以下示例类<code>Foo</code>和嵌套类<code<Bar</code<,所有内容都是<code>constexpr</code>: 我想测试调用<code>Foo::DoTheThing</code>返回1: 海湾合作委员会和Clang都在这里抱怨,但MSVC没有 GCC表示: 错误: ,或者如果我将< code>Bar的定义移到< code>Foo之外,我可以让GCC和Clang

  • 我有以下设计,我想在Kotlin中实现: null 有没有更好的,更Kotlin的方法?

  • 问题内容: 我正在在线阅读有关Java中嵌套接口的一些文章[1] [2],我知道 但是我不确定 简而言之,“嵌套接口始终是静态的”是真的吗? [1] https://beginnersbook.com/2016/03/nested-or-inner-interfaces-in- java/ [2] https://www.programcreek.com/2013/08/inner-interfa

  • 问题内容: 我很难用Java的非静态嵌套类来解决问题。考虑以下示例,该示例先显示“ Inner”,然后显示“ Child”。 我知道Inner实例始终必须与Outer实例相关联,这也适用于Child,因为它扩展了Inner。我的问题是语法的含义- 为什么调用内部构造函数? 我只看到一个用于调用超类构造函数和调用重写方法的超类版本的纯文本,但从未使用过这种形式。 问题答案: 这称为“合格的超类构造函

  • 这个问题相当复杂,我不知道以前是否有人问过,因为我不知道如何在搜索框中表达这个问题。 下面是代码: 静态成员将在更多静态方法中再次使用,但我需要首先将其时区设置为“UTC”。有没有方法调用<code>。setTimeZone(“UTC”)一劳永逸?或者我必须调用<code>。setTimeZone(“UTC”)在每个静态方法中?