问题描述
我在 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
和另一个声明,这样我们就可以像 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