Jef*_*f G 1 c++ templates template-specialization c++17
我有如下代码,将模板类型映射到枚举值。但是,MyEnum::C仅当代码使用 template 时才定义该值something<double>。有没有办法更改模板声明/定义,以便可以编译以下内容?
例如,我想如果我在模板声明的末尾添加一个默认模板参数something,就足以使完整的专业化成为部分专业化,这只会在使用时编译专业化。但是,我无法找出正确的语法来执行此操作。
#include <iostream>
using namespace std;
enum class MyEnum
{
A,
B
};
template<typename T>
struct something;
template<>
struct something<int>
{
static constexpr auto value = MyEnum::A;
};
template<>
struct something<double>
{
static constexpr auto value = MyEnum::C;
};
int main()
{
cout << static_cast<int>(something<int>::value) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为以下内容会起作用,但没有:
template<typename T>
constexpr MyEnum toEnum()
{
if constexpr (std::is_same_v<int, T>)
return MyEnum::A;
else if constexpr (std::is_same_v<double, T>)
return MyEnum::C;
}
Run Code Online (Sandbox Code Playgroud)
即使您something<double>根据其他模板参数将完全专业化更改为部分专业化T,您仍然不能MyEnum::C在该专业化内部使用并期望您的程序格式良好,因为MyEnum::C是一个非依赖的构造,编译器可能会拒绝包含无效的模板非依赖构造,即使这些模板从未被实例化。
出于同样的原因,坚持MyEnum::C到废弃的if constexpr分支并不会使程序有效。
但是,您可以执行以下操作:
template<typename T, typename E = MyEnum>
struct something;
template<>
struct something<int>
{
static constexpr auto value = MyEnum::A;
};
template<typename E>
struct something<double, E>
{
static constexpr auto value = E::C;
};
Run Code Online (Sandbox Code Playgroud)
现在,你不再直接提及MyEnum::C;依赖构造E::C可能有效也可能无效,具体取决于是否E实际上最终成为MyEnum。
我不知道这个策略是否适合您的特定用例。