問題描述
我在 C++ 中有這樣一個(gè)模板
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.
我如何聲明我的模板來做到這一點(diǎn)?
How can I declare my template to do that ?
我讀過這個(gè)問題,但答案是使用宏,這不好:模板c++的模板?
I've read this question but the answer is using macros, that's not nice: template of template c++?
我可以通過沒有宏的模板來做到這一點(diǎn)嗎?我使用的是 Visual C++ 2013.
can I do this by just template without macros ? I'm using Visual C++ 2013.
推薦答案
UPDATE
c++17 引入了P0127R2 使用 auto 聲明非類型模板參數(shù)",允許聲明非類型模板使用 auto
作為實(shí)際類型占位符的參數(shù):
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
是一個(gè)非類型模板參數(shù).它的類型可以通過 decltype(P)
推斷出來.
That is, P
is a non-type template parameter. Its type can be inferred with decltype(P)
.
auto
遵循眾所周知的推導(dǎo)和偏序規(guī)則.在您的情況下,可以將類型限制為僅接受指針:
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 {};
請注意,即使對于更詳細(xì)的檢查,使用 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)> {};
也可以使用推斷類型作為其他模板參數(shù)的約束:
It's also possible to use the inferred type as a contraint for other template parameters:
template <auto I, decltype(I)... Is>
struct List {};
<小時(shí)>
舊答案
既然您問的是一個(gè)沒有宏定義幫助的基于類模板的純解決方案,那么答案很簡單:至于現(xiàn)在(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.
這個(gè)問題已經(jīng)被 WG21 C++ 標(biāo)準(zhǔn)委員會(huì)確定為需要,并且有幾個(gè)建議讓模板自動(dòng)推斷非類型模板參數(shù)的類型.
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 隱式模板參數(shù):
此示例的目的是消除對冗余 template
習(xí)語的需要.這個(gè)習(xí)語被廣泛使用,在谷歌上的點(diǎn)擊量超過 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.
目標(biāo)是能夠替換像template
和另一個(gè)聲明,這樣我們就可以像 C<&X::f>
一樣實(shí)例化模板,而不必說 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