微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Visual Studio 2019 中使用枚举作为模板参数时出现错误 C2440 和 C2973

如何解决在 Visual Studio 2019 中使用枚举作为模板参数时出现错误 C2440 和 C2973

在使用 Visual Studio 2019 编译此代码时出现两个错误 C2440 和 C2973:

#include <iostream>
#include <array>

enum class First {
    SOME_VALUE,OTHER_VALUE
};

enum class Second {
    PRIME,BIS
};


template<First FirsT_VAL>
struct FirstData {
    int i;
};

template<Second SECOND_VAL>
struct SecondData {
    long l;
};

template<First FirsT_VAL,Second SECOND_VAL>
class Data :public SecondData<SECOND_VAL>,public FirstData<FirsT_VAL> {

};

template<First FirsT_VAL>
struct WithFirstData {
    virtual const FirstData<FirsT_VAL >& getData() = 0;
    virtual ~WithFirstData() = default;
};

template<Second SECOND_VAL>
struct WithSecondData {
    virtual const SecondData<SECOND_VAL>& getData() = 0;
    virtual ~WithSecondData() = default;
};

template<First FirsT_VAL,Second SECOND_VAL>
class WithData : public WithFirstData<FirsT_VAL>,public WithSecondData<SECOND_VAL> {

public:
    const First First;
    const Second Second;
private:

    const Data<FirsT_VAL,SECOND_VAL> data;
public:

    virtual const Data<FirsT_VAL,SECOND_VAL>& getData() {
        return data;
    }

    template<typename ... DataArgs>
    WithData(DataArgs &&... data) :First(FirsT_VAL),Second(SECOND_VAL),data(std::forward<DataArgs>(data)...) {    }

    virtual ~WithData() {};
};

class ConcreteWithData : public WithData<First::SOME_VALUE,Second::BIS> {
public:
    ConcreteWithData() : WithData() {
    }
};

std::ostream& operator<<(std::ostream& ostream,const ConcreteWithData& o) {
    ostream << static_cast<int>(o.First);
    return ostream;
}
int main() {

    ConcreteWithData ev;
    std::cout << "Hello World!\n" << ev;
}

错误消息除外:

1>C:\[...]\Test.cpp(55): error C2440: 'specialization': cannot convert from 'int' to 'First'
1>C:\[...]\Test.cpp(55): message : Conversion to enumeration type requires an explicit cast (static_cast,C-style cast or function-style cast)
1>C:\[...]\Test.cpp(55): error C2440: 'specialization': cannot convert from 'int' to 'Second'
1>C:\[...]\Test.cpp(55): message : Conversion to enumeration type requires an explicit cast (static_cast,C-style cast or function-style cast)
1>C:\[...]\Test.cpp(55): error C2973: 'Event': invalid template argument 'int'
1>C:\[...]\Test.cpp(44): message : see declaration of 'Event'
1>C:\[...]\Test.cpp(44): error C2440: 'specialization': cannot convert from 'int' to 'First'
1>C:\[...]\Test.cpp(44,36): message : Conversion to enumeration type requires an explicit cast (static_cast,C-style cast or function-style cast)
1>C:\[...]\Test.cpp(44): error C2440: 'specialization': cannot convert from 'int' to 'Second'
1>C:\[...]\Test.cpp(44,70): message : Conversion to enumeration type requires an explicit cast (static_cast,C-style cast or function-style cast)
1>C:\[...]\Test.cpp(44,1): error C2973: 'WithSecondData': invalid template argument 'int'
1>C:\[...]\Test.cpp(38): message : see declaration of 'WithSecondData'

有趣的是,这在 gcc (g++.exe (Rev6,Built by MSYS2 project) 10.2.0) 下编译没有问题。 谁错在这里?我做了一些编译器不应该理解的事情;或 vs 编译器无法正确理解枚举;或者 gcc 允许它不应该的东西?

编辑 2:

如果我将它重构为无作用域的枚举和整数作为模板参数,它就会编译,所以有一个变通方法,但我希望能够使用有作用域的枚举。而且,更重要的是,我很想首先了解出了什么问题。

编辑 1:

原始代码有点大,我把它简化了一点,但基本上我想要实现的是根据不同的枚举值对 FirstData 和 SecondData 的不同数据进行专业化。因此,我可以在引用不同的具体实现时使用对 WithFirstData<SOME_VALUE> WithSecondData<PRIME> 的引用,并确保这些实现具有我正在寻找的数据。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。