Как легко static_assert(false)
в else{}
из if constexpr
?
#include <type_traits>
#include <iostream>
class B{};
class C{};
class D{};
template<class T> void complexIf(){
if constexpr(std::is_same_v<T,B>){
//^ actually it is some complex statement
std::cout<<"1"<<std::endl;
}else if constexpr(std::is_same_v<T,C>){
//^ another uber complex thingy
std::cout<<"2"<<std::endl;
}
//another 4-5 "else if constexpr(){}"
else{//#1
static_assert(false);
}
};
int main(){
complexIf<B>();// should compliable
//complexIf<D>() should uncompliable
}
Приведенный выше MCVE не компилируется.
Причина была объяснена в constexpr, если и static_assert .
(Этот вопрос больше относится к языковым юристам.)
В этом вопросе я хотел бы знать элегантный обходной путь.
Мои плохие решения
Первый обходной путь (условие копирования и вставки в #1
): -
else{//#1
static_assert(std::is_same_v<T,B> &&std::is_same_v<T,C> );
//^ a ton of copy-paste condition
}
^ Это менее ремонтопригодно + грязно.
Моя вторая попытка (кешировать как constexpr bool
): -
template<class T> void complexIf(){
constexpr bool case1=std::is_same_v<T,B>;
constexpr bool case2=std::is_same_v<T,C>;
if constexpr(case1){
//^ actually it is some complex statement
std::cout<<"1"<<std::endl;
}else if constexpr(case2){
//^ another uber complex thingy
std::cout<<"2"<<std::endl;
}
//another 4-5 "else if constexpr(){}"
else{//#1
static_assert(case1&case2 );
}
}
^ Это менее ясно и довольно запутанно.
В реальном мире complexIf
— это функция для управления пользовательскими интеллектуальными указателями.
Каждая if constexpr
в основном связана с проверкой типа указателей.
always_false<T>
). - person Bob__   schedule 05.03.2019