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

odr使用变量的模板静态constexpr定义

经伟
2023-03-14

实际代码更复杂,但我能够将其简化为这个示例。

在我尝试获取指向MyPackets\u t::type的指针(在main()中取消对foo()的注释调用)之前,一切都正常

此时,为了使应用程序链接,类型需要定义。

我正在努力寻找正确的定义语法。已注释掉模板。。。应该做到这一点。但是,它生成了一个错误“PacketCollection::types的模板参数与原始模板不匹配”。

尝试这样的东西-模板

我试着用MyPackets\u t代替PacketCollection——结果是一样的。

如果我使数据包集合非模板化,那么一切都会按预期编译和运行。

我觉得我要么错过了一些非常基本的东西,要么编译器中有一个错误。我在gcc 4.8和4.9中得到了这种行为。

Clang 3.5对这种情况有一个稍微不同的理解:constexpr静态数据成员“类型”的声明需要一个初始值设定项。

到目前为止,我找到的唯一解决方法是使用

static constexpr std::array<int, 2> types() { return {1,2}; }

相反,但我不喜欢这个解决方案。如果变量在非模板版本中工作(使用标头中的初始值设定项),那么它也应该适用于模板版本。

#include <iostream>

using namespace std;

class Packet_A
{
public:
    static constexpr int TYPE = 1;
};

class Packet_B
{
public:
    static constexpr int TYPE = 2;
};

template <typename T> class PacketCollection
{
public:
    static constexpr size_t size = 2;
    static constexpr int types[size] { 1, 2 };
};

typedef PacketCollection<Packet_A> MyPackets_t;

//template<typename T> constexpr int PacketCollection<Packet_A>::types[PacketCollection<Packet_A>::size];

void foo(const int* bar, size_t size)
{
    if (size >= 2)
    {
        cout << bar[0] << bar[1];
    }
}

int main(int argc, char* argv[])
{
    cout << Packet_A::TYPE;
    cout << MyPackets_t::types[0];

    //foo(MyPackets_t::types, MyPackets_t::size);

    return 0;
}

共有1个答案

隆扬
2023-03-14

您应该使用T而不是Packet\u A

template<typename T> constexpr int PacketCollection<T>::types[PacketCollection<T>::size];
                                                    ^                          ^

请参阅实时示例。

 类似资料:
  • 我想确认这个代码是合法的(还是不合法的?)C++17。 如果用G++和MSVC编译,我不会得到错误(并得到正确的输出), 但Intel和clang给出了一个错误: 使用编译(对于MSVC)。 在godbolt和我的本地机器上尝试了最新的编译器。

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

  • 如果我在函数中有一个变量(例如,一个大数组),那么同时声明<code>static</code>和<code>constexpr</code>有意义吗保证数组是在编译时创建的,所以是否无用? 实际上是否在生成的代码或语义方面做了什么?

  • 问题内容: 我已经定义了一个对象并声明了一个静态变量。在该方法中,当我尝试打印实例和类变量时,两者都打印相同的值。 不是实例变量吗?它应该打印0而不是50吗? 问题答案: 不,只有一个变量-您尚未声明任何实例变量。 不幸的是,Java允许您访问静态成员,就像通过相关类型的引用访问静态成员一样。这是IMO的设计缺陷,某些IDE(例如Eclipse)允许您将其标记为警告或错误- 但这是语言的一部分。您

  • template module在Ansible中非常常用,而它在使用的时候又没有显示的指定template文件中的值,所以有时候用户会对template文件中使用的变量感到困惑,所以在这里又重新强调下。 template变量的定义 在playbook中定义的变量,可以直接在template中使用,同时facts变量也可以直接在template中使用,当然也包含在inventory里面定义的host

  • 我试图在变量函数模板上使用'decltype'来获取其返回值类型,然后使用它来定义成员变量。但我一直在犯这样的错误: 基本上,decltype失败并将声明为int,而不是推断的返回类型。 它的工作原理是当我提供的所有参数的值,但这不是我要找的行为。因为我不知道该函数有多少参数,所以它必须保持为可变模板函数。 我计划如何使用类模板的示例: 如果我没有任何成员变量,并使用作为: 它编译,因此我相信能够