【发布时间】:2021-03-21 09:41:48
【问题描述】:
使用 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> 的引用,并确保这些实现具有我正在寻找的数据。
【问题讨论】:
-
我不太清楚你想用该代码实现什么。介意在你的问题中详细说明一下吗?
-
您的代码还有许多其他问题,但看起来确实像编译器错误。 clang 和 gcc 在修复错误后进行编译。
-
我建议您可以将此问题提交给Microsoft DC。
标签: c++ visual-studio visual-c++ c++17