gpt4 book ai didi

c++ - 类型别名模板参数包

转载 作者:行者123 更新时间:2023-11-30 01:38:23 25 4
gpt4 key购买 nike

在下面的示例中,我主要尝试为模板参数包设置别名。

这在标准中是不可能的,所以我发现人们使用元组或空模板结构来解决这个限制。但是我的情况似乎有所不同,因为我没有要匹配的参数参数类型包...

(我知道这个示例看起来很愚蠢,但它是一个最小的 PoC。在代码库中,类型列表变得更长,这真的很有用。)

#include <iostream>
#include <tuple>

template<typename T>
void f(T t)
{
std::cout << "templated f()" << std::endl;

}
template<>
void f(int t)
{
std::cout << "specialized f()" << std::endl;
}

template<typename A, typename B>
void fn()
{
f(A());
}

template<int, char>
void fn()
{
int a;
f(a);
}

// Can't seem to define this correctly.
//using MyType = std::tuple<int, char>()::type;

int
main(int, char**)
{
fn<char, char>();

// I have
fn<int, char>();

// I want some alias;
//fn<MyType>();

return 0;
}

引用文献;

最佳答案

如果我们使用模板化的空结构作为类型包的别名,则可以在您的原始函数上使用 SFINAE,以便在为我们的特殊结构调用它时,它只是转发封装的类型包到原始实现。

这是在 C++14 中的样子:

template <typename... Types>
struct TypePack {};

// Helper meta functions to determine
// if the template param is a TypePack struct.
template <typename... Ts>
static constexpr bool is_typepack_v = false;

template <typename... Ts>
static constexpr bool is_typepack_v<TypePack<Ts...>> = true;

template <typename... Ts>
// Enabled whenever template parameter is not a TypePack.
typename std::enable_if<not is_typepack_v<Ts...>>::type
fn() { // FN_A
std::cout << "Generic\n";
}

template <>
// Complete specialization, selected over generic fn for <char,int>
void fn<char,int> () { // FN_B
std::cout << "Specialized for char,int\n";
}

template <typename T>
// Enabled when template param is a TypePack.
typename std::enable_if<is_typepack_v<T>>::type
fn() { // FN_C
forward_fn(T{});
}

// forward_fn() extracts the types from a TypePack argument
// and invokes fn with it.
template <typename ...T>
void forward_fn(TypePack<T...> /*unused*/) {
std::cout << "Forwarding a pack alias\n";
fn<T...>();
}

// To alias a type pack use TypePack<T1,T2..,Tn>
using CharIntPack = TypePack<char,int>;

int main() {
fn<char,char>(); // invokes FN_A
fn<char,int>(); // invokes FN_B
fn<CharIntPack>(); // invokes FN_C which then invokes FN_B
return 0;
}

这会产生以下输出:

Generic
Specialized for char,int
Forwarding a pack alias
Specialized for char,int

我喜欢这种方法的地方在于,这个“技巧”在定义函数时只需要一次,用户可以完全忽略它。

关于c++ - 类型别名模板参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47995472/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com