C++模板参数类型推断

时间:2023-03-10
本文介绍了C++模板参数类型推断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我在 C++ 中有这样一个模板

I have such a template in C++

template<typename T, T* P> struct Ptr {};

所以我可以这样使用它:

so I can use it as such:

const int i = 0;
Ptr<int, &i> ptr;

Ptr<decltype(i), &i> ptr;

但我不想指定类型 int 或身份 i 两次,我只想使用

But I don't want to specify the type int or identity i twice, I want to use just

Ptr<&i> ptr;

并让编译器自己找出 int 类型部分.

and let the compiler figure out the int type part by itself.

我如何声明我的模板来做到这一点?

How can I declare my template to do that ?

我读过这个问题,但答案是使用宏,这不好:模板c++的模板?

I've read this question but the answer is using macros, that's not nice: template of template c++?

我可以通过没有宏的模板来做到这一点吗?我使用的是 Visual C++ 2013.

can I do this by just template without macros ? I'm using Visual C++ 2013.

推荐答案

UPDATE

c++17 引入了P0127R2 使用 auto 声明非类型模板参数",允许声明非类型模板使用 auto 作为实际类型占位符的参数:

c++17 introduced "P0127R2 Declaring non-type template parameters with auto", allowing to declare a non-type template parameter(s) with auto as a placeholder for the actual type:

template <auto P> struct Ptr {};

也就是说,P 是一个非类型模板参数.它的类型可以通过 decltype(P) 推断出来.

That is, P is a non-type template parameter. Its type can be inferred with decltype(P).

auto 遵循众所周知的推导和偏序规则.在您的情况下,可以将类型限制为仅接受指针:

auto in a template parameter list is subject to well-known deduction and partial ordering rules. In your case, the type can be constrained to accept pointers only:

template <auto* P> struct Ptr {};

请注意,即使对于更详细的检查,使用 auto 的语法也足够了,例如:

Note that the syntax utilizing auto is sufficient even for more detailed inspection, e.g.:

template <typename F>
struct FunctionBase;

template <typename R, typename... Args>
struct FunctionBase<R(*)(Args...)> {};

template <auto F>
struct Function : FunctionBase<decltype(F)> {};

也可以使用推断类型作为其他模板参数的约束:

It's also possible to use the inferred type as a contraint for other template parameters:

template <auto I, decltype(I)... Is>
struct List {};

<小时>

旧答案

既然您问的是一个没有宏定义帮助的基于类模板的纯解决方案,那么答案很简单:至于现在(2014 年 12 月,c++14) 不可能.

Since you are asking about a pure class template-based solution without the help of macro definitions then the answer is simple: as for now (Dec 2014, c++14) it is not possible.

这个问题已经被 WG21 C++ 标准委员会确定为需要,并且有几个建议让模板自动推断非类型模板参数的类型.

This issue has been already identified by the WG21 C++ Standard Committee as a need and there are several proposals to let templates automatically infer the type of non-type template arguments.

最接近的是N3601 隐式模板参数:

此示例的目的是消除对冗余 template 习语的需要.这个习语被广泛使用,在谷歌上的点击量超过 10 万次.

Implicit template parameters

The purpose of this example is to eliminate the need for the redundant template<typename T, T t> idiom. This idiom is widely used, with over 100k hits on Google.

目标是能够替换像template这样的模板声明.struct C; 和另一个声明,这样我们就可以像 C<&X::f> 一样实例化模板,而不必说 C.

The goal is to be able to replace a template declaration like template<typename T, T t> struct C; with another declaration so that we can instantatiate the template like C<&X::f> instead of having to say C<decltype(&X::f), &X::f>.

基本思想是能够说template;struct C {/* ... *