在模板专用化中强制出现编译时错误
Force a compile time error in a template specialization
我最近开始学习现代模板元编程,并为自己编写了一个类型的index_of函数。
template<std::size_t Index, class C, class A> struct mp_index_of_impl{};
template<std::size_t Index, class C,template<class...> class A,class ...Ts>
struct mp_index_of_impl<Index,C,A<C,Ts...>>{
using type = std::integral_constant<std::size_t,Index>;
};
template<std::size_t Index, class C,template<class...> class A,class ...Ts,class T1>
struct mp_index_of_impl<Index,C,A<T1,Ts...>>{
using type = typename mp_index_of_impl<Index + 1,C,A<Ts...>>::type;
};
template<std::size_t Index, class C,template<class...> class A> struct mp_index_of_impl<Index,C,A<>>{
//static_assert(false,"Does not contain type");
using type = std::integral_constant<std::size_t,0>;
};
问题是我最后一次专业化
template<std::size_t Index, class C,template<class...> class A>
struct mp_index_of_impl<Index,C,A<>>{
//throw a compile error here
};
我试着像这个一样使用static_assert
template<std::size_t Index, class C,template<class...> class A> struct mp_index_of_impl<Index,C,A<>>{
static_assert(false,"Does not contain type");
};
但这每次都会抛出一个编译错误,即使它不匹配。
如果这个模板专用化匹配,我想抛出一个带有自定义错误消息的编译错误。我该怎么做?
如果将static_assert(false,...)
放入模板专用化中,则始终无法从中生成有效代码。这是格式错误,不需要诊断。
解决方法是使static_assert
依赖于模板参数:
template<typename T>
struct assert_false : std::false_type
{ };
template <typename T>
inline T getValue(AnObject&)
{
static_assert( assert_false<T>::value , "Does not contain type");
}
在这里获得一个真正格式良好的解决方案有点烦人。你遇到了〔temp.res〕/8:
如果没有有效的专业化为模板生成,并且该模板未实例化,模板格式错误,没有诊断必需。。。如果模板的假设实例化立即由于不依赖于模板参数的构造,遵循其定义将是不成形的,程序格式不正确;不需要进行诊断。
所以我们需要做的是避免任何可能导致static_assert(false, ...)
的事情。在这种情况下,我们有一个部分开口。我们可以专门研究只剩下一种类型的情况,并断言这就是我们想要的:
template<std::size_t Index, class C,template<class...> class A, class Last>
struct mp_index_of_impl<Index,C,A<Last>>{
static_assert(std::is_same<C, Last>::value,"Does not contain type");
using type = std::integral_constant<std::size_t, Index>;
};
这不会处理空列表的情况,但在顶级,您可以添加另一个非空的static_assert
:
template<std::size_t Index, class C,template<class...> class A>
struct mp_index_of_impl<Index,C,A<>>{ };
template <typename T> is_empty : std::false_type { };
template <template <class...> class A> is_empty<A<>> : std::true_type { };
template <class C, class X>
struct mp_index_of
: mp_index_of_impl<0, C, X>
{
static_assert(!is_empty<X>::value, "Does not contain type");
};
尽管在实践中,TartanLlama的解决方案可能会让每个编译器都满意,我可能只会使用它
相关文章:
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 如何在常量计算表达式中获取编译时错误?
- C++根据调用的构造函数强制编译时错误
- 使用 std::iterator_traits<> 时编译时错误不明确
- is_same和variadic模板编译时错误无效转换
- 私有运营商删除会触发 GCC 和 Clang 的编译时错误,但不会在 MSVC 上触发编译时错误
- 运行时与编译时多态性:更好的可读性与编译时错误检查,更重要的是
- 引发编译时错误
- 为什么调用不明确的 ctor 时没有编译时错误?
- 在 sizeof 运算符上强制编译时错误
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 从Mac上的终端编译时C 错误
- 使用MINGW-W64使用-M32选项(32位代码)编译时错误
- C++线程错误 - 带有类参数的编译时错误
- 如果编译时间构量参数是错误的,则生成编译时错误
- 尝试调用指向成员函数的函数指针时出现编译时错误
- 编译时错误:删除了联合默认构造函数
- 初始化启动对象时出现编译时错误
- 在模板专用化中强制出现编译时错误
- 调用专用模板函数时强制编译时错误