从模板类中调用模板函数

发布于 2024-10-14 02:13:39 字数 934 浏览 4 评论 0原文

GCC 不会编译以下代码片段(这实际上是 GCC 的正确行为,因为它符合我已经学过的标准 C++。但是 VC++ 会编译。)

template<class T>
void CUDAMemory1D2DTextureAllocator<T>::allocateMemoryOnDevice()
{
    m_pChannelDesc = cudaCreateChannelDesc<T>();
    ...
}

正如我通过搜索已经发现的那样,需要告诉编译器认为 cudaCreateChannelDesc 是模板方法。否则它会尝试 将 < 解析为小于运算符...

以下代码片段在一个简单的示例中显示了这一点:

template< typename G >
struct Test
{
    template< typename T > T f() const;
};

template< typename G, typename T >
void g()
{
    Test< G > t;

    t.f< T >();           // ERROR: gcc won't compile that
    t.template f< T >();  // OK: now gcc knows that f is a template method an treads the following angle brackets  not as operators but as template brackets...
} 

到目前为止一切顺利。现在我的问题是,在上面的情况下,我调用的方法是 cudaCreateChannelDesc ,它不属于任何类或命名空间,该怎么办? 非常欢迎任何如何解决这种情况的意见或建议。

谢谢

GCC will not compile following code snippet (which in fact is correct behavior of GCC as it is conform to the standard C++ as I have learned already. VC++ however will compile.)

template<class T>
void CUDAMemory1D2DTextureAllocator<T>::allocateMemoryOnDevice()
{
    m_pChannelDesc = cudaCreateChannelDesc<T>();
    ...
}

As i already found out by searching is, that one needs to tell the compiler that cudaCreateChannelDesc is a template method. Otherwise it will try to
parse < as a smaller than operator...

The following snippet shows that in an easy example:

template< typename G >
struct Test
{
    template< typename T > T f() const;
};

template< typename G, typename T >
void g()
{
    Test< G > t;

    t.f< T >();           // ERROR: gcc won't compile that
    t.template f< T >();  // OK: now gcc knows that f is a template method an treads the following angle brackets  not as operators but as template brackets...
} 

So far so good. Now my question is, how to do that in the above case, where the method I call is cudaCreateChannelDesc which does not belong to any class or namespace?
Any advice or suggestion how to solve this situation are very welcome.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜柠檬 2024-10-21 02:13:39

如果它不属于任何类或命名空间,您可以直接调用它,例如:cudaCreateChannelDesc()。不是这样工作的吗?

You can call it directly like: cudaCreateChannelDesc<T>() if it doesn't belong to any class or namespace. Isn't it working like that?

尛丟丟 2024-10-21 02:13:39

我假设 cudaCreateChannel1Desc 不是全局或命名空间函数,因为它应该可以工作,除非您忘记了包含或命名空间解析。你确实说它是一个“方法”,即成员函数。

因此,如果它是类 CUDAMemory1D2DTextureAllocator 的方法,那么您应该使用 this->template cudaCreateChannel1DES() 来调用该方法(我推断出的是CUDAMemory1D2DTextureAllocator 的模板化基类的方法 下面是在不同情况下有效和无效的简要说明(至少在 gcc 上):

template <class G>
struct Base {

  template< class T > 
  T h() const {
    std::cout << "Hello World!" << std::endl;
  };
};

template< class G >
struct Test : public Base<G>
{
    template< class T > 
    T f() const {
      std::cout << "Hello World!" << std::endl;
    };

    void callF() const {
      f<G>();                //works!
      this->f<G>();          //works!
      h<G>();                //ERROR!
      this->h<G>();          //ERROR!
      this->template h<G>(); //works!
    };
};

I'm assuming that cudaCreateChannel1Desc is not a global or namespace function, because that should work, unless you forgot an include or a namespace resolution. And you do say it is a "method", i.e. a member function.

So, if it is a method of class CUDAMemory1D2DTextureAllocator, then you should use this->template cudaCreateChannel1Desc<T>() to call that method (which I have deduced is a method of a templated base class of CUDAMemory1D2DTextureAllocator. Below is a compact illustration of what works and what doesn't in different situations (at least on gcc):

template <class G>
struct Base {

  template< class T > 
  T h() const {
    std::cout << "Hello World!" << std::endl;
  };
};

template< class G >
struct Test : public Base<G>
{
    template< class T > 
    T f() const {
      std::cout << "Hello World!" << std::endl;
    };

    void callF() const {
      f<G>();                //works!
      this->f<G>();          //works!
      h<G>();                //ERROR!
      this->h<G>();          //ERROR!
      this->template h<G>(); //works!
    };
};
你是年少的欢喜 2024-10-21 02:13:39

cudaCreateChannelDesc 函数是否在您范围内的某个命名空间中声明?看来您可能遇到两阶段名称查找问题,这要求模板中引用的某些实体(如函数)即使在实例化模板之前也必须可见。如果您在定义 allocateMemoryOnDevice 的同一位置编写一个非模板化函数并在其中调用 cudaCreateChannelDesc,代码是否可以编译?如果没有,您可能缺少 #includecudaCreateChannelDesc 上的命名空间限定。

Is the cudaCreateChannelDesc function declared in some namespace that you have in scope? It appears that you might be having a problem with two-phase name lookup, which requires that some entities (like functions) referred to in templates need to be visible even before the template is instantiated. If you write a non-templated function in the same place as you definition of allocateMemoryOnDevice and call cudaCreateChannelDesc inside it, does the code compile? If not, you might be missing a #include or a namespace qualification on cudaCreateChannelDesc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文