c++ - 为什么指针类型转换不适用于模板非类型参数

标签 c++ templates c++11

我有以下代码:

template <const char *p>
struct A{};

template <int i>
struct E{};

extern constexpr int i = 0;
constexpr float f = 0.f;
extern constexpr char c = 0;
int main(int argc, const char *argv[])
{
  A<&c> b; //works
  A<(const char *)(&i)> a; //Error: could not convert template argument ‘(const char*)(& i)’ to ‘const char*’
  E<(int)f> e; //works
  return 0;
}

为什么是 A<(const char *)(&i)> a;是错的?我用 g++-4.6.1 和 -std=c++0x 编译它。

编辑:正如查尔斯建议的 reinterpret_cast在常量表达式中是不允许的,我把上面的代码改成如下:

struct Base{};
struct Derived : public Base {};

template <const Base *p>
struct A{};

extern constexpr Base base = {};
extern constexpr Derived derived = {};
A<&base> a; //works
A<(const Base*)&derived> b; //error: could not convert template argument ‘(const Base*)(& derived)’ to ‘const Base*’

因此,不仅reinterpret_cast不被允许。使用 A<static_cast<const base*>(&derived)产生同样的错误。

致@BЈовић:

  A<(const Base*)(0)> b; // error: could not convert template argument ‘0u’ to ‘const Base*’

最佳答案

至于“标准如此”的答案,请看评论。

真正的问题是为什么不允许这样做?

在模板参数中断然拒绝类型转换是很有意义的,因为您真正感兴趣的是模板参数的值。 然而,类型转换可能会变得任意复杂,并且不会被强制为 constexpr s。标准(显然)根本不会对内置(原始)类型进行异常(exception)处理。

请注意,您的 E<(int)f>示例也被 clang 驳斥原因:

error: non-type template argument of type 'int' is not an integral constant expression

为什么 gcc 允许这样做是可疑的,但我认为它允许您使用 constexpr s 你可以明确声明。请注意,这是不可能偷偷i 的地址的。 A的参数列表中.

关于c++ - 为什么指针类型转换不适用于模板非类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12137840/

相关文章:

python - Django 模板 {% if %} : what does it take to be equal?

c++ - 在 C++11 中以无锁方式原子交换两个 std::atomic<T*> 对象?

c++ - 使用 std::conditional_variable 等待条件

c++ - 在给定 Sum 的未排序数组中配对

c++ - 在双向链表中添加函数导致无限循环

python - 如何在python中运行c代码

c++ - 如果在 C++ 中没有先前声明的情况下定义自由函数,是否会隐式内联?

html - 从模板中管理标题导航菜单的最佳方式?

python - 是否有 C++11 等同于 Python 的 @property 装饰器?

c++ - 是否需要删除包含对象的 "pair"?