【问题标题】:Clang bug? Using pointer as template argument铿锵虫?使用指针作为模板参数
【发布时间】:2020-07-11 03:03:48
【问题描述】:

我想使用指针作为模板参数。通常,这可以正常工作。 但更进一步,我希望通过另一个模板类声明这些指针。

我在 GCC 上运行良好,但在 Clang 上却失败了。

这里有一个小程序来演示(live link):

template <size_t ID = 0>
struct PointerHolderT {
    static thread_local char *smt_pStorage;
};
template <size_t ID>
thread_local char *PointerHolderT<ID>::smt_pStorage = nullptr;

template<char **ppData>
struct MyClass {
    static void foo() {
        cout << "this is my ptr: " << ppData << endl;
    }
};

int main() {
    MyClass<&PointerHolderT<123>::smt_pStorage>::foo(); 
    return 0;
}

错误是:

error: non-type template argument of type 'char **' is not a constant expression

正如您从实时链接中更详尽的示例中看到的那样,当它是一个普通的全局指针时,当它是一个普通结构内的指针时,clang 可以很好地处理它。只有在 templated 结构中使用指针时才会出现问题。

  • 这是一个clang错误吗?
    • 或者我的行为是否违法,但 GCC 允许?
  • 有人知道解决方法,所以我可以在 clang 上解决这个问题吗?

【问题讨论】:

  • 我刚刚用 MSVC 试过了,它也不能编译。 'MyClass': template parameter 'ppData': 'smt_pStorage': a variable with non-static storage duration cannot be used as a non-type argument 我认为这实际上可能是一个 GCC 错误。
  • 如果我删除thread_local,它会编译。

标签: c++ templates clang clang++


【解决方案1】:

我猜是thread_local 的问题。如果我将thread_local 也添加到pData 中,则编译失败。

【讨论】:

  • 我想原因如下:对于一个普通的全局变量,整个程序有一个对象(对于模板,所以每种类型一个,但无论如何),所以这是有道理的能够在编译时获取其地址。但是线程局部代表在运行时为每个线程创建和销毁的许多对象,并且它没有固定地址(每个线程在自己的地址获取自己的变量)。在这个问题中,即使 ,也无法理解变量的地址是什么。也许MyClass 的参数应该是一个返回引用的函子?
  • @HTNW:那么你认为 GCC 的行为是荒谬的吗?
  • @jwd 可能是某种 GCC 扩展;你必须检查手册。但是如果你不想将自己锁定在 gcc 中,你显然不能依赖它。
猜你喜欢
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
  • 2013-12-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多