Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ MSVC '=' unable to resolve function overload

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • 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

>Solution :

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading