Ошибка VC ++ при использовании указателя на функцию шаблона - PullRequest
7 голосов
/ 27 мая 2011

Я пытаюсь написать функцию обратного вызова шаблона для libcurl.Однако при использовании указателя на экземпляр функции шаблона VC ++ 2008 и 2010 продолжают выдавать мне эту ошибку:

template-callback.cpp (27): ошибка C2664: 'curl_easy_setopt': не можетпреобразовать параметр 3 из 'size_t (__cdecl *) (void *, size_t, size_t, void *)' в '...' Контекст не допускает устранения неоднозначности перегруженной функции

Но GCC (4.5.1) компилирует код без проблем.Это урезанная версия кода:

#include <string>

template<typename String>
size_t callback(
    void*       ptr
  , size_t  size
  , size_t  nmemb
  , void*       userdata
)
{
  //String* str = static_cast<String*>(userdata);
  size_t    len = size*nmemb;
  //str->append(static_cast<char const*>(ptr), len);
  return len;
}

typedef size_t (*write_callback)(void*, size_t, size_t, void*);
struct CURL;
enum CURLOption { none };
void curl_easy_setopt(CURL*, CURLOption, ...);

void f()
{
  CURL* curl = NULL;
  CURLOption option = none;

  // This gives an error
  curl_easy_setopt(curl, option, &callback<std::string>);

  // This doesn't
  write_callback cb = &callback<std::string>;
  curl_easy_setopt(curl, option, cb);
}

Это ошибка в VC ++ или я что-то не так делаю?

1 Ответ

1 голос
/ 27 мая 2011

Я воспроизвел проблему на ideone (C ++ 03 с gcc-4.3.4):

#include <iostream>

typedef void (*FuncType)(int);

void foo(FuncType);
void bar(...);

template <typename T>
void callback(T t) { std::cout << t << "\n"; }

int main() {
  foo(&callback<int>); // OK
  bar(static_cast<FuncType>(&callback<int>)); // OK
  bar(&callback<int>); // error: address of overloaded function
                       // with no contextual type information
}

Похоже, что проблема возникает из-за взаимодействия аргумента variadic и указателя функции.

Примечание: в режиме C ++ 0x с gcc-4.5.1 работает нормально

Я предполагаю, что проблема связана с разрешением перегрузки bar (или curl_easy_setopt в вашем случае).

Проблема в том, что для использования многоточия компилятор решает, как передать аргумент: int, double, pointer, ... Кажется, что он не может решить, сам, что тип &callback<int>.

Когда мы используем foo или выполняем приведение, это однозначно, потому что выбора нет.

Я подозреваю, что проблема с конвертацией, но у меня нет версии стандарта C ++ 03, которую можно было бы изучить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...