У меня есть следующий код, который сопоставляет типы шаблонов с перечисляемым значением. Однако значение MyEnum::C определяется только тогда, когда в коде используется шаблон 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;
}
Я думал, что следующее сработает, но не сработало:
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;
}
Перечисление генерируется из внешнего инструмента. Нет связанного макроса.





Даже если вы изменили полную специализацию 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;
};
Теперь вы больше не упоминаете MyEnum::C; зависимая конструкция E::C может быть действительной или нет, в зависимости от того, действительно ли E оказывается MyEnum.
Подходит ли эта стратегия для вашего конкретного случая использования, я понятия не имею.
Что удаляет
Cиз перечисления? Наверно макрос? Нельзя ли тем же макросом отключить свою специализацию? Пожалуйста, предоставьте более подробную информацию.