在 C++ 中使用枚举作为模板类型参数

发布于 2024-09-15 01:52:38 字数 960 浏览 3 评论 0原文

在 C++ 中使用枚举作为模板(类型)参数是否有任何限制/问题?

示例:

enum MyEnum
{
    A, B, C, D, E
};

template <typename _t>
class MyTemplate
{
public:
   _t value;

   void func(const _t& param) { /* .... */ }
};

// ....

MyTemplate<MyEnum> MyInstance;

我在 Win32/x86 上通过 VS 2008 (SP1) 使用 MSVC++ 的实际问题是与使用枚举作为模板参数的类相关的几个编译错误(= 编译器报告的错误)。不幸的是,由于我的项目变得有点复杂(您可以将其视为设计错误:P),引发这些错误的模板类是派生的、嵌套的,甚至专门针对具有枚举模板参数的类。

尝试构建时,编译器会在只有注释的行中报告许多错误/无用的错误,例如“C2059:语法错误:'public'”。其中许多问题我可以通过用与示例中类似的方法替换 const _t& 来修复。 param by _t (即复制参数),但我既无法修复所有这些错误,也不知道为什么这“有帮助”。 **我知道,上面的简单示例编译时没有错误。

使用 int 而不是 enum,我的项目编译时没有错误。

预先感谢您的任何提示或提示!


编辑

毕竟,我认真地认为这是一个编译器错误。当我尝试用简化的代码重现错误时,我只在所有“构建”的 50% 中得到了这些错误,不是很确定:
例如尝试编译,它报告了这些错误。重建 - 没有变化。删除了评论,构建 - 没有变化。重建 - 然后:没有错误,编译正常。

我已经遇到了一些编译器错误(我猜在 20k 行代码内有 2 或 3 个错误),但这个在我看来非常奇怪。
有什么建议如何确定它是否编译器吗?

are there any restrictions / problems using an enum as template (type) argument in C++?

Example:

enum MyEnum
{
    A, B, C, D, E
};

template <typename _t>
class MyTemplate
{
public:
   _t value;

   void func(const _t& param) { /* .... */ }
};

// ....

MyTemplate<MyEnum> MyInstance;

My actual problem using MSVC++ via VS 2008 (SP1) on Win32/x86 are several compilation errors (= errors reported by the compiler) in association with classes using enums as template arguments. As my project unfortunately has become a bit complex (you can consider that as a design error :P), the template classes raising these errors are derived, nested and even specialised on a class with enum template parameter.

Trying to build, the compiler reports many wrong/useless errors such as "C2059: syntax error: 'public'" in lines where there is only a comment. Many of them I could fix by replacing in methods similar to the one in the example the const _t& param by _t (i.e. copying the parameter), but neither could I fix all of these errors nor do I have a clue why this "helps". **I know, the simple example above compiles w/o errors.

Using int instead of enum, my project compiles w/o errors.

Thanks in advance for any hint or tip!


Edit:

After all, I seriously consider this as a compiler bug. When I tried to reproduce the errors with simplified code, I got them only in 50 % of all "builds", not very deterministic:
E.g. tried to compile, and it reported these errors. Rebuild - no change. Deleted a comment, build - no change. Rebuild - and then: no errors, compiles fine.

I've already met a few compiler bugs (2 or 3 I guess within 20k lines of code), but this one seems to me very strange.
Any suggestions how to figure out if it is the compiler?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

反差帅 2024-09-22 01:52:38

是的,有限制。例如,根据 C++03 14.3.1[temp.arg.type]/2,您不能使用匿名枚举作为模板参数

本地类型、没有链接的类型、未命名类型或由任何这些类型复合的类型不得用作模板类型参数的模板参数。

因此以下代码在 C++03 中无效:

template <typename T>
void f(T) {}

enum {A};

int main() {
  f(A);
}

但在 C++11 中有效。

Yes, there are restrictions. For example, you cannot use an anonymous enum as a template argument according to C++03 14.3.1[temp.arg.type]/2

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

So the following code is not valid in C++03:

template <typename T>
void f(T) {}

enum {A};

int main() {
  f(A);
}

It is valid in C++11 though.

私野 2024-09-22 01:52:38

参考原来的问题:

在 C++ 中使用枚举作为模板(类型)参数是否有任何限制/问题?

我没有找到——而且我认为也不存在。这可能是一个坏主意,因为这种技术并不经常使用,因此可能会存在一些(更多)与此相关的编译器错误,正如 Potatoswatter 所说。
考虑以下示例:

enum MyEnum : int
{
    A, B, C, D
};

template <typename _t> class MyTemplate
{
public:
    void print()
    {
        cout << "not using any specialisation" << endl;
    }
};
    template <> class MyTemplate <MyEnum>
    {
    public:
        void print()
        {
            cout << "MyEnum specialisation" << endl;
        }
    };
    template<> class MyTemplate <int>
    {
    public:
        void print()
        {
            cout << "int specialisation" << endl;
        }
    };

template <typename _t> void print(_t param)
{
    MyTemplate<_t> m;
    m.print();
}


int main()
{
    print(A);
    print(5);

    return 0;
}

输出为:

MyEnum 专业化
int专业化

对于这些简单的示例,一切正常且符合预期,并且枚举与任何其他类型作为模板类型参数一样完美地工作(= 我没有看到任何问题的原因)。

最初,我在问题中引入了示例来展示我对该问题的含义(枚举作为模板类型参数,显示作为成员或方法参数类型的可能用法等)。为了提供一些背景知识,即为什么我问这个问题(想象一下我问“int 是否有任何问题”),我提到了编译我的实际项目时出现的这些奇怪的问题。
很抱歉,我无法提取其本身完整的片段并重现错误,至少我能得到的是将 2k 行代码分成 4 个文件,其中“语法错误:'public'”和其他一些当我编译项目时出现语法错误,并且在删除注释或重新构建(=删除中间文件)时,它们在某些情况下出现/消失。不幸的是,重建对原始项目没有帮助,我不得不将专业化从枚举类型替换为 int。

所以,感谢大家的提示和技巧。在我看来,潜在的问题似乎是一个编译器错误,这使得这个问题有点毫无意义,因为答案似乎只是“不 - 使用枚举作为模板类型参数没有任何限制”。带来不便敬请谅解。

Referring to the original question:

are there any restrictions / problems using an enum as template (type) argument in C++?

I didn't find any - and I don't think there are any. It might turn out to be a bad idea because this technique it is not used that often, so there might be a few (more) compiler bugs relating to this, just as Potatoswatter said.
Consider the following example:

enum MyEnum : int
{
    A, B, C, D
};

template <typename _t> class MyTemplate
{
public:
    void print()
    {
        cout << "not using any specialisation" << endl;
    }
};
    template <> class MyTemplate <MyEnum>
    {
    public:
        void print()
        {
            cout << "MyEnum specialisation" << endl;
        }
    };
    template<> class MyTemplate <int>
    {
    public:
        void print()
        {
            cout << "int specialisation" << endl;
        }
    };

template <typename _t> void print(_t param)
{
    MyTemplate<_t> m;
    m.print();
}


int main()
{
    print(A);
    print(5);

    return 0;
}

The output is:

MyEnum specialisation
int specialisation

For these simple examples, everything works fine and as expected and the enum works perfectly as any other type as template type argument (= I don't see any reason for problems).

Originally, I introduced the example in the question to show what I meant with that question (enum as template type argument, show possible usages as member or method argument type and so on). To provide a bit of background, i.e. why I asked that question (imagine I asked "are there any problems with int"), I mentioned these strange problems compiling my actual project.
I'm sorry I could not extract a snippet of it that is complete in itself and reproducing the errors, the least I could get were 2k lines of code splitted into 4 files, where a "syntax error : 'public'" and some other syntax error were raised when I compiled the project, and they appeared / disappeared under certain circumstances, when deleting a comment or re-building (= deleting the intermediate files). Unfortunately, rebuilding does not help with the original project, where I had to replace a specialisation from an enum type to int.

So, thanks everyone for your hints and tips. The underlying problem seems to me to be a compiler bug, what makes the question a bit pointless, as the answer seems to be just "no - there are no restrictions using an enum as template type argument". Sorry for the inconvenience.

ま昔日黯然 2024-09-22 01:52:38

MSVC 处理枚举(值)模板参数的方式很奇怪。有时,枚举会不正确地提升为 int,并且运算符定义不正确。看来他们并没有真正使用 enum 类型测试模板引擎。

证明这是一个编译器错误很简单:将有效代码放入并观察它是否成功编译。 您的示例显然是合规的,因此问题(或错误,无论如何)是他们的。

编辑:经过仔细检查,您说该示例不 重现该错误。在您提供一个可以帮助您的示例之前,我们或任何其他人都无法帮助您。

MSVC handles enum (value) template parameters strangely. Enums are promoted to int improperly sometimes and the operators aren't defined properly. It seems that they don't really test the template engine with enum types.

Proving it's a compiler bug is simple: put valid code in and observe whether it successfully compiles. Your example is obviously compliant, so the problem (or the mistake, anyway) is theirs.

Edit: on closer inspection you say that the example does not reproduce the bug. Neither we nor anyone else can help you until you produce an example that does.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文