你可以实现一个自定义的类型特征来按索引获取模板参数。
以下是一个快速且简陋的实现示例,该实现依赖于std::tuple
和std::tuple_element_t
,但你也可以选择不使用这些工具并正确地实现(如果需要的话)。
#include <tuple>
#include <type_traits>
template <int I, typename T>
struct template_param;
template <std::size_t I, template <typename...> typename T, typename... TArgs>
struct template_param<I, T<TArgs...>>
{
using type = std::remove_pointer_t<std::tuple_element_t<I, std::tuple<TArgs*...>>>;
};
template <int I, typename T>
using template_param_t = typename template_param<I, T>::type;
然后在代码中这样使用它:
#include <type_traits>
template <typename TTask, typename TMutex>
struct GuiApplication
{
};
struct Task;
struct Mutex;
int main()
{
auto app = GuiApplication<Task, Mutex>{};
static_assert(std::is_same_v<template_param_t<0, decltype(app)>, Task>);
static_assert(std::is_same_v<template_param_t<1, decltype(app)>, Mutex>);
}
不过请注意,这种方法并不能解决你编译失败的例子,它只是获取模板参数的一种替代方法。
为了真正解决你的错误,我更倾向于采用Jan Schultke建议的方法,即通过别名化GuiApplication
并让编译器自动推导所有内容。