在模板类中实例化自由模板函数

发布于 2024-11-19 01:09:14 字数 1992 浏览 0 评论 0原文

我需要在模板类(TC)中实例化一个免费模板函数(FTF)。 FTF将TC的模板参数之一作为模板参数。 TC 还保存指向这些 FTF 的通用指针,并且通过指针调用这些函数。

获取指向 FTF 的指针的步骤不足以实例化它,并且我收到来自 GCC 工具链的链接器错误。 MSDN 说明了 FTF 规范如此 - - 但是,我的 FTF 实例化依赖于我的 TC 的模板参数,因此 FTF 实例化不能放置在自由范围内。

这可能吗?我附加了一些基本的生成代码,问题出在类 test_service 的构造函数中,我在其中将自由函数的指针分配到自定义容器中。我收到链接器错误,告诉我找不到自由函数(未实例化)。我知道在类中的某处指定对模板函数的调用将产生实例化,但是我只会通过指针进行调用。

#include "rpc_common.h"
#include <boost/cstdint.hpp>

namespace rubble { namespace rpc {

  struct test_service_dummy_tag{};

  template<typename T>
  class test_service_skel
  {
  public:
    bool Init() {}
    bool TearDown() {}
    bool test_one(TestRequest,TestResponse){};
  private:
  };

  template<typename T_IMPL>
  bool test_service_test_one(T_IMPL & impl,ClientRequest & request)
  {
    return 0;
  }

  template<typename T_IMPL=test_service_skel<test_service_dummy_tag> >
  class test_service
  {
  public:
    test_service()
    {
      // uncomment the following two lines and a instantiation will occur.
      // ClientRequest cr;
      //test_service_test_one<T_IMPL>(m_impl,cr);
      m_dispatch_table.SetEntry( Oid("test_one",0),(void *)  & test_service_test_one<T_IMPL>);
    }
    bool Init() { return m_impl.Init(); };
    bool TearDown() { return m_impl.TearDown(); };
  private:
    T_IMPL m_impl;
    OidContainer<Oid,void *> m_dispatch_table;
  };


} }

编辑:独立的最小版本

 class test_skel
    {
      bool test_function()
      {
        return true;
      }
    };


    template<typename T>
    bool test_function()
    {

    }

    template<typename T = test_skel>
    class test
    {
    public:
      test()
      {
        dispatch = (void *) & test_function<T>;
      }
      void * dispatch;
    };

    int main()
    {
      test<> t;
      return 0;
    }

I need to instantiate a free template function (FTF) within a template class (TC). The FTF takes as a template parameter one of the template parameters of the TC. The TC also holds generic pointers to these FTF's, and these functions are called through the pointers.

The step of taking a pointer to a FTF is not enough to instantiate it, and I receive linker errors from the GCC toolchain. MSDN illustrates FTF specification as so -- however my instantion of the FTF is dependant on a template parameter of my TC, and therefore the FTF instantiation cannot be placed in free scope.

Is this possible ? I am attaching some basic generated code, the issue is in the constructor of the class test_service, where I assign the pointer of a free function into a custom container. I get a linker error telling me the free function cannot be found (uninstantiated). I know that specifying a call to the template function in the class somewhere will produce a instantiation, however I am only going to be making a call via a pointer.

#include "rpc_common.h"
#include <boost/cstdint.hpp>

namespace rubble { namespace rpc {

  struct test_service_dummy_tag{};

  template<typename T>
  class test_service_skel
  {
  public:
    bool Init() {}
    bool TearDown() {}
    bool test_one(TestRequest,TestResponse){};
  private:
  };

  template<typename T_IMPL>
  bool test_service_test_one(T_IMPL & impl,ClientRequest & request)
  {
    return 0;
  }

  template<typename T_IMPL=test_service_skel<test_service_dummy_tag> >
  class test_service
  {
  public:
    test_service()
    {
      // uncomment the following two lines and a instantiation will occur.
      // ClientRequest cr;
      //test_service_test_one<T_IMPL>(m_impl,cr);
      m_dispatch_table.SetEntry( Oid("test_one",0),(void *)  & test_service_test_one<T_IMPL>);
    }
    bool Init() { return m_impl.Init(); };
    bool TearDown() { return m_impl.TearDown(); };
  private:
    T_IMPL m_impl;
    OidContainer<Oid,void *> m_dispatch_table;
  };


} }

EDIT: self-contained minimal version

 class test_skel
    {
      bool test_function()
      {
        return true;
      }
    };


    template<typename T>
    bool test_function()
    {

    }

    template<typename T = test_skel>
    class test
    {
    public:
      test()
      {
        dispatch = (void *) & test_function<T>;
      }
      void * dispatch;
    };

    int main()
    {
      test<> t;
      return 0;
    }

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

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

发布评论

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

评论(2

○愚か者の日 2024-11-26 01:09:14

如果您不使用 void*,即: http:// www.ideone.com/eRgUG

但是,如果您坚持将指针存储在void*中,那么您需要使用特定函数获取地址先指针然后强制转换 - 例如

    bool (*temp)() = &test_function<T>;
    dispatch = reinterpret_cast<void*>(temp); // YUCK

这为编译器提供了足够的上下文为您生成地址。

啊 - 刚刚看到 DeadMG 的答案,生成 void* 的函数更简洁......

There is no problem iff you don't use a void*, i.e.: http://www.ideone.com/eRgUG

However, if you insist on storing the pointer in a void*, then you need to take the address using a specific function pointer first and then cast - e.g.

    bool (*temp)() = &test_function<T>;
    dispatch = reinterpret_cast<void*>(temp); // YUCK

This gives the compiler enough context to generate the address for you.

Ahh - just saw DeadMG's answer, the function to generate the void* is neater...

圈圈圆圆圈圈 2024-11-26 01:09:14

当没有发生重载时,使用 MSVC,您的独立示例不会为我编译,并出现有关重载函数的奇怪错误。不过,我确实设法解决了这个问题。

class test_skel
{
    bool test_function()
    {
        return true;
    }
};

template<typename T> void* to_void_pointer(T t) {
    return reinterpret_cast<void*>(t);
}

template<typename T>
bool test_function()
{
    return true;
}

template<typename T = test_skel>
class test
{
public:
    test()
    {
        dispatch = to_void_pointer(&test_function<T>);
    }
    void * dispatch;
};

int main()
{
    test<> t;
    return 0;
}

这编译得很干净。我怀疑您所看到的和我所看到的任何行为都是编译器错误。

Your self-contained example wouldn't compile for me with a strange error about overloaded functions, when there is no overloading going on, with MSVC. I did, however, manage to work around it.

class test_skel
{
    bool test_function()
    {
        return true;
    }
};

template<typename T> void* to_void_pointer(T t) {
    return reinterpret_cast<void*>(t);
}

template<typename T>
bool test_function()
{
    return true;
}

template<typename T = test_skel>
class test
{
public:
    test()
    {
        dispatch = to_void_pointer(&test_function<T>);
    }
    void * dispatch;
};

int main()
{
    test<> t;
    return 0;
}

This compiles cleanly. I suspect that whatever behaviour you're seeing and I saw is a compiler error.

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