在处理编译时字符串时(变量列表char
)操作,我需要实现一种方法来检查编译时字符串是否包含另一个(较小的)编译时字符串。
这是我的第一次尝试:
template<int I1, int I2, typename, typename> struct Contains;
template<int I1, int I2, char... Cs1, char... Cs2>
struct Contains<I1, I2, CharList<Cs1...>, CharList<Cs2...>>
{
using L1 = CharList<Cs1...>;
using L2 = CharList<Cs2...>;
using Type = std::conditional_t
<
(I1 >= sizeof...(Cs1)),
std::false_type,
std::conditional
<
(L1::template at<I1>() != L2::template at<I2>()),
typename Contains<I1 + 1, 0, L1, L2>::Type,
std::conditional
<
(I2 == sizeof...(Cs2) - 1),
std::true_type,
typename Contains<I1 + 1, I2 + 1, L1, L2>::Type
>
>
>;
};
我发现这个解决方案非常容易阅读和推理。很遗憾,它不起作用.
编译器总是尝试实例化每个分支std::conditional
,甚至那些没有被采取的。换句话说,短路没有发生。
这导致Contains
被无限实例化。
我通过分离每个来解决了我原来的问题std::conditional
块在单独的模板类中,其中条件结果作为部分特化进行处理。
它有效,但不幸的是我发现它很难阅读/修改。
有没有办法延迟实例化模板类型并接近我原来的解决方案?
我想我可以将贪婪实例化的模板包装在如下类型中:
DeferInstantiation<typename Contains<I1 + 1, 0, L1, L2>::Type>
这应该可以防止模板参数的贪婪实例化。
是否有可能以某种方式实施DeferInstantiation<T>
?