Если вы можете добавить специальное значение ошибки в SpiDmaTxStreams
enum ... скажем, SpiDmaTxStreams::ErrorValue
... Я предлагаю другое решение, опять же на основе шаблонной структуры, но с обращенной логикой: не специализированная структура и одиночная специализированная версия для static_error
сообщений.
Я имею в виду ... если вы вернете SpiDmaTxStreams::ErrorValue
в случае недопустимой комбинации
constexpr SpiDmaTxStreams spiDmaTxStream(DmaId dmaId, DmaStreamId streamId) {
switch (dmaId) {
case DmaId::DMA_1:
switch (streamId) {
case DmaStreamId::Stream_4:
return SpiDmaTxStreams::Dma1Stream4;
// ...
default:
return SpiDmaTxStreams::ErrorValue; // <<---- add this
break;
}
case DmaId::DMA_2:
switch (streamId) {
case DmaStreamId::Stream_1:
return SpiDmaTxStreams::Dma2Stream1;
// ...
default:
return SpiDmaTxStreams::ErrorValue; // <<---- add this
break;
}
}
// report compile-time error "invalid DMA-stream combination"
}
Вы можете позвонить spiDmaTxStream()
, чтобы присвоить значение значению шаблона (осторожно: код не проверен) следующим образом
template <DmaId I1, DmaStreamId I2,
SpiDmaTxStreams IR = spiDmaTxStream(I1, I2)>
struct foo
{ static constexpr auto value = IR; };
template <DmaId I1, DmaStreamId I2>
struct foo<I1, I2, SpiDmaTxStreams::ErrorValue>
{
// where DmaId::DMA_1/DmaStreamId::Stream_4 is an
// acceptable combination
static_assert( (I1 == DmaId::DMA_1) && (I2 == DmaStreamId::Stream_4),
"your error message here" );
};
и опять вместо
constexpr value id = spiDmaTxStream(DmaId::DMA_2, DmaStreamId::Stream_1);
Вы можете написать
constexpr value id = foo<DmaId::DMA_2, DmaStreamId::Stream_1>::value;
Если dmaId
/ streamId
неприемлемо, spiDmaTxStream()
возвращает SpiDmaTxStreams::ErrorValue
, поэтому активируется специализированная версия foo
и отправляется сообщение static_error()
.