C++ 阻止编译完整模板专项化

C++ Prevent Compilation of Full Template Specialization

提问人:Jeff G 提问时间:8/1/2023 更新时间:8/1/2023 访问量:61

问:

我有如下代码,用于将模板类型映射到枚举值。但是,仅当代码使用模板时,才会定义该值。有没有办法更改模板声明/定义,以便编译以下内容?MyEnum::Csomething<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;
}

我以为以下方法会起作用,但没有:

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;
}
C++ C++17 模板专业化

评论

1赞 HolyBlackCat 8/1/2023
什么从枚举中删除?大概是一个宏?你不能用同一个宏禁用你的专业化吗?请提供更多详情。C
0赞 Jeff G 8/1/2023
枚举是从外部工具生成的。没有关联的宏。

答:

7赞 Brian Bi 8/1/2023 #1

即使您根据其他一些模板参数将完全专用化更改为部分专用化,您仍然不能在该专用化内部使用,并期望您的程序格式正确,因为程序是非依赖构造,编译器可能会拒绝包含无效非依赖构造的模板,即使这些模板从未实例化。something<double>TMyEnum::CMyEnum::C

出于同样的原因,坚持使用丢弃的分支不会使程序有效。MyEnum::Cif 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;
};

现在,你不再直接提到;依赖构造可能有效,也可能无效,具体取决于最终是否实际为 。MyEnum::CE::CEMyEnum

我不知道这种策略是否适合您的特定用例。