我正在尝试构建一个可变模板类。通常,实例化的每一级都需要通过切掉一种类型然后使用其余类型来实例化“下一级”。对于我的最终级别,与其专注于一种类型,我宁愿提供一些基本案例类型并避免重复实际逻辑。
我添加了一个 std::conditional
打开 BaseCase
当其余类型由空参数包组成时。
class BaseCase { };
template <typename T, typename... Ts>
class VariadicClass;
template <typename... Ts>
using NextLevel = typename std::conditional<
sizeof...(Ts) != 0, VariadicClass<Ts...>, BaseCase>::type;
template <typename T, typename... Ts>
class VariadicClass {
T this_level; // whatever
NextLevel<Ts...> next_level; // fails when Ts is empty
};
问题是VariadicClass
是基于至少一个类型参数的模板,所以当它达到基本情况时( Ts
为空),尝试使用 std::conditional
使用 VariadicClass<>
, 这当然会失败。
我的解决方案是编写一些特定的函数并使用 decltype
与重载一起使用,而不是使用 std::conditional
完全没有。
template <typename... Ts>
VariadicClass<Ts...> type_helper(Ts&&...);
BaseCase type_helper();
template <typename... Ts>
using NextLevel = decltype(type_helper(std::declval<Ts>()...));
现在,这行得通,但如果每次我有一个可变参数类时我都想保持这种做法,这似乎很乏味。有没有办法使用 std::conditional
或类似的东西来实现这种效果而不必写出那么多针对特定问题的代码?
最佳答案
推迟评估。
template<class T>struct identity{
template<class...>using result=T;
};
template<template<class...>class src>
struct delay{
template<class...Ts>using result=src<Ts...>;
};
template <typename... Ts>
using NextLevel =
typename std::conditional<
sizeof...(Ts) != 0, delay<VariadicClass>, identity<BaseCase>
>::type::template result<Ts...>;
identity
忽略 Ts...
并返回其参数。 delay
采用模板
并应用Ts...
。虽然签名看起来很可疑,但它确实有效。
关于c++ - std::conditional 的可变模板使用,其中一种类型是实例化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25539439/