C++ MSVC '='无法解决函数过载问题

发布于 2025-01-13 23:06:26 字数 2347 浏览 2 评论 0原文

我有一个 API,可以将多个函数指针注册为回调。但是,我需要在调用回调时跟踪其他数据(在本例中为索引)。我想要做的是在编译时生成一堆方法来保存这些附加数据。我的代码如下:

    #include <iostream>
    #include <vector>
    #include <sstream>
    #include <array>
    
    // API function format
    typedef void ( *Function )( const std::string& msg );
    
    // My function accepting the API interface + an additional index
    void callback( const size_t index, const std::string& msg ) {
      std::cout << "(" << index << "): " << msg << std::endl;
    }
    
    // Wrapper for my function in API format generating the index
    template <size_t METHOD_INDEX>
    void wrapper( const std::string& msg ) {
      return callback( METHOD_INDEX, msg );
    }
    
    // Constexpr Array which should be built on compile time, containing all wrappers
    template <size_t SIZE>
    struct Array {
      constexpr Array() : arr() {
        for ( auto i = 0; i < SIZE; ++i ) {
          arr[ i ] = wrapper<i>; // Error at this line
        }
      }
    
      size_t size() const {
        return SIZE;
      }
    
      void ( *arr[ SIZE ] )( const std::string& );
    };
    
    int main() {
      static constexpr auto wrappers = Array<5>();
    
      // Emulating registering wrapper functions at the API
      const auto NUM_CALLBACKS = 5;
      std::vector<Function> apiCallbacks( NUM_CALLBACKS );
      for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
        apiCallbacks[ i ] = wrappers.arr[ i ];
      }
    
      // Emulating API is calling registered functions
      for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
        apiCallbacks[ i ]( "Test" );
      }
    }

在源代码中标记的行处,编译器 (MSVC x64 16.8) 抛出错误:

main.cpp(25,1): error C2563: mismatch in formal parameter list
main.cpp(23): message : while compiling class template member function 'Array<5>::Array(void)'
main.cpp(37): message : see reference to class template instantiation 'Array<5>' being compiled
main.cpp(25,1): error C2568: '=': unable to resolve function overload
main.cpp(25,1): message : could be 'void wrapper(const std::string &)'

我还无法弄清楚

  • 为什么编译器会抛出错误?
  • 如何修复该代码?

有人可以回答我这两个问题并解释一下问题吗? 提前致谢

I have an API which I'm able to register multiple function pointer as callbacks. However I need to track additional data when a callback is called (in this example an index). What I want to do is generate a bunch of methods at compile which holds this additional data. My code is the following:

    #include <iostream>
    #include <vector>
    #include <sstream>
    #include <array>
    
    // API function format
    typedef void ( *Function )( const std::string& msg );
    
    // My function accepting the API interface + an additional index
    void callback( const size_t index, const std::string& msg ) {
      std::cout << "(" << index << "): " << msg << std::endl;
    }
    
    // Wrapper for my function in API format generating the index
    template <size_t METHOD_INDEX>
    void wrapper( const std::string& msg ) {
      return callback( METHOD_INDEX, msg );
    }
    
    // Constexpr Array which should be built on compile time, containing all wrappers
    template <size_t SIZE>
    struct Array {
      constexpr Array() : arr() {
        for ( auto i = 0; i < SIZE; ++i ) {
          arr[ i ] = wrapper<i>; // Error at this line
        }
      }
    
      size_t size() const {
        return SIZE;
      }
    
      void ( *arr[ SIZE ] )( const std::string& );
    };
    
    int main() {
      static constexpr auto wrappers = Array<5>();
    
      // Emulating registering wrapper functions at the API
      const auto NUM_CALLBACKS = 5;
      std::vector<Function> apiCallbacks( NUM_CALLBACKS );
      for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
        apiCallbacks[ i ] = wrappers.arr[ i ];
      }
    
      // Emulating API is calling registered functions
      for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
        apiCallbacks[ i ]( "Test" );
      }
    }

At the line marked in the source code the compiler (MSVC x64 16.8) throws an error:

main.cpp(25,1): error C2563: mismatch in formal parameter list
main.cpp(23): message : while compiling class template member function 'Array<5>::Array(void)'
main.cpp(37): message : see reference to class template instantiation 'Array<5>' being compiled
main.cpp(25,1): error C2568: '=': unable to resolve function overload
main.cpp(25,1): message : could be 'void wrapper(const std::string &)'

I wasn't able to figure out yet

  • why the compiler throws an error?
  • how to fix that code?

Can someone answer me that 2 questions and explain the problem?
Thanks in advance

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

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

发布评论

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

评论(1

記柔刀 2025-01-20 23:06:26

问题是使用变量i作为模板参数。正确的方法是使用整数序列,它提供了一组可用作模板参数的编译时常量:

#include <iostream>
#include <vector>
#include <sstream>
#include <array>
#include <utility>
#include <cstddef>

// API function format
typedef void ( *Function )( const std::string& msg );

// My function accepting the API interface + an additional index
void callback( const size_t index, const std::string& msg ) {
  std::cout << "(" << index << "): " << msg << std::endl;
}

// Wrapper for my function in API format generating the index
template <size_t METHOD_INDEX>
void wrapper( const std::string& msg ) {
  return callback( METHOD_INDEX, msg );
}

template <::std::size_t... x_index>
constexpr auto make_wrappers_impl(::std::index_sequence<x_index...>)
{
    return ::std::array<Function, sizeof...(x_index)>{&wrapper<x_index>...};
}

template <::std::size_t x_size>
constexpr auto make_wrappers(void)
{
    return make_wrappers_impl(::std::make_index_sequence<x_size>());
}

int main() {
  static constexpr auto wrappers{make_wrappers<5>()};

  // Emulating registering wrapper functions at the API
  const auto NUM_CALLBACKS = 5;
  std::vector<Function> apiCallbacks( NUM_CALLBACKS );
  for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
    apiCallbacks[ i ] = wrappers[ i ];
  }

  // Emulating API is calling registered functions
  for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
    apiCallbacks[ i ]( "Test" );
  }
}

在线编译器

The problem is the use of variable i as template parameter. The proper approach is to use integer sequence which provides a pack of compile-time constants that can be used as template parameters:

#include <iostream>
#include <vector>
#include <sstream>
#include <array>
#include <utility>
#include <cstddef>

// API function format
typedef void ( *Function )( const std::string& msg );

// My function accepting the API interface + an additional index
void callback( const size_t index, const std::string& msg ) {
  std::cout << "(" << index << "): " << msg << std::endl;
}

// Wrapper for my function in API format generating the index
template <size_t METHOD_INDEX>
void wrapper( const std::string& msg ) {
  return callback( METHOD_INDEX, msg );
}

template <::std::size_t... x_index>
constexpr auto make_wrappers_impl(::std::index_sequence<x_index...>)
{
    return ::std::array<Function, sizeof...(x_index)>{&wrapper<x_index>...};
}

template <::std::size_t x_size>
constexpr auto make_wrappers(void)
{
    return make_wrappers_impl(::std::make_index_sequence<x_size>());
}

int main() {
  static constexpr auto wrappers{make_wrappers<5>()};

  // Emulating registering wrapper functions at the API
  const auto NUM_CALLBACKS = 5;
  std::vector<Function> apiCallbacks( NUM_CALLBACKS );
  for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
    apiCallbacks[ i ] = wrappers[ i ];
  }

  // Emulating API is calling registered functions
  for ( auto i = 0; i < NUM_CALLBACKS; ++i ) {
    apiCallbacks[ i ]( "Test" );
  }
}

online compiler

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