指针作为非类型模板参数 [英] pointer as non-type template argument

查看:118
本文介绍了指针作为非类型模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回答这个SO问题时,我发现在标准(已经是C ++ 03,仍然在C + 11),你只能使用地址作为非类型模板参数,如果它们是& id-expression (加上一些例外)。

When answering this SO question, I found in the Standard (already C++03, still in C++11) that you can only use addresses as non-type template arguments if they're of the form & id-expression (plus some exceptions).

但我不能回答为什么

But I couldn't answer why this is the case.


14.3.2模板非类型参数[temp.arg.nontype]

14.3.2 Template non-type arguments [temp.arg.nontype]

非模板,非模板模板参数的模板参数应为以下之一:

A template-argument for a non-type, non-template template-parameter shall be one of:

[...]

- 常数表达式(5.19),用于指定静态存储>持续时间和外部或内部链接或具有外部或内部链接的函数的地址,包括函数模板和函数模板id,但不包括非静态类成员,表示(忽略括号)为& id-expression ,除了&如果名称引用函数或数组,则可以省略,并且如果相应的模板参数是引用则将被省略; [...]

— a constant expression (5.19) that designates the address of an object with static storage > duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; [...]

(n3485,强调我的)

(n3485, emphasis mine)

using TFoobar = int (*)();
template < TFoobar tp > struct foo_struct{};

int foobar() { return 42; }
constexpr TFoobar pFoobar = &foobar;

foo_struct < &foobar > o0; // fine
foo_struct < pFoobar > o1; // ill-formed

我想它与翻译阶段有关,不太了解地址。然而,为什么不允许呢?编译器应该不可能使用类似于宏替换的替换来替换 pFoobar & foobar

I guess it has something to do with the translation phases, namely the compiler doesn't know much about addresses. Yet, why isn't it allowed? Shouldn't it be possible for the compiler to use something similar to macro substitution to replace pFoobar with &foobar?

推荐答案

考虑类 Foo<& X> $ c> Foo<& Y> ,两者都使用静态成员 int Bar 。链接器必须能够判断你的程序是否有1或2个 Bar 对象。现在考虑链接器也是最有可能负责为& X & Y 赋值的一方。

Consider classes Foo<&X> and Foo<&Y>, both with a static member int Bar. The linker must be able to tell whether your program has 1 or 2 Bar objects. Now consider that the linker is also the party most likely responsible for assigning values to &X and &Y.

再次查看标准。在编写时,编译器不需要将实际的地址传送给链接器。相反,它传递 id-expression 。链接器已经能够确定两个 id-expression 是否相同,即使在为它们分配数字地址之前。

Look at the Standard again. As it's written, the compiler doesn't need to communicate the actual address to the linker. Instead, it passes the id-expression. Linkers are already quite capable of determining whether two id-expression's are the same, even before assigning a numerical address to them.

这篇关于指针作为非类型模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆