【发布时间】:2016-12-11 10:29:56
【问题描述】:
考虑关注
struct dummy{};
dummy d1;
dummy d2;
template<dummy* dum>
void foo()
{
if (dum == &d1)
; // do something
else if (dum == &d2)
; // do something else
}
现在,可以像这样调用foo了
foo<&d1>();
foo<&d2>();
一切都按预期进行。但以下没有
constexpr dummy* dum_ptr = &d1;
foo<dum_ptr>();
Visual Studio 出现此错误
错误 C2975:
dum_ptr:foo的模板参数无效,预期的编译时常量表达式
虽然这有效
constexpr dummy& dum_ref = d1;
foo<&dum_ptr>();
在 Visual Studio 中,但不在 G++ 中,因为
注意:模板参数扣除/替换失败:
错误:& dum_ref不是dummy*的有效模板参数,因为它不是变量的地址foo<&dum_ref>();
编辑:
由于 C++17,std::addressof 被标记为 constexpr,所以我猜它应该可以工作。
【问题讨论】:
-
foo<dum_ptr>();在 g++ 中也不起作用。 -
有趣。我用
-std=c++1z试过了,它可以工作,但你是对的。它不适用于-std=c++14。 -
模板中可能是
dummy const * dum或dummy constexpr * dum? -
我很惊讶。它如何与位置无关代码(PIC)、全局偏移表(GOT)和过程链接表(PLT)一起工作?这些地址不是有时只能在运行时定义吗?这个 constexpr 地址有什么魔力?
标签: c++11 language-lawyer