gpt4 book ai didi

c++ - 如何让 C++ 编译器间接推导 T?

转载 作者:可可西里 更新时间:2023-11-01 17:39:07 26 4
gpt4 key购买 nike

我的模板符比较弱。我有这段代码:

template<typename T>
void Foo(void(*func)(T*)) { }

void Callback(int* data) { }

int Test()
{
Foo(Callback);
}

...但我想要比 C 的 void(*func)(T*) 讨厌的函数指针语法更具可读性的东西。

我团队中有人建议这样做:

template<typename T>
struct Types
{
typedef void Func(T*);
};

template<typename T>
void Foo2(typename Types<T>::Func* func) {}

void Test2()
{
Foo2(Callback); // could not deduce template argument for 'T'
Foo2<int>(Callback); // ok
}

(我仍在争论这是否实际上更具可读性,但这是一个单独的问题。)

我怎样才能帮助编译器找出 T 是什么而不需要在调用者中明确指定它?

最佳答案

您可以使用特征类从函数类型中提取 T

template<class F>
struct CallbackTraits;

template<class T>
struct CallbackTraits<void(*)(T)>
{
typedef T ArgumentType;
};

你的例子可以这样修改:

template<typename F>
void Foo(F func)
{
typedef typename CallbackTraits<F>::ArgumentType T;
}

void Callback(int* data) { }

int Test()
{
Foo(Callback);
}

boost type-traits 库中使用了此技术: http://www.boost.org/doc/libs/1_57_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html

这篇博文更详细地介绍了该技术的实现: https://functionalcpp.wordpress.com/2013/08/05/function-traits/

不幸的是,这种方法在 Foo 的签名中隐藏了关于传入参数的约束的信息。在上面的示例中,参数必须是 void(T*) 类型的函数

此替代语法与原始示例的作用相同,但可读性稍强:

template<typename T>
void Foo(void func(T*)) { }

另一种可能更具可读性的替代语法可以使用 c++11 的别名模板实现,如下所示:

template<typename T>
using Identity = T;

template<typename T>
void Foo(Identity<void(T*)> func) { }

不幸的是,最新的 MSVC 无法编译它,报告内部编译器错误。

关于c++ - 如何让 C++ 编译器间接推导 T?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27566409/

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