使用指向模板函数的指针时出现VC ++错误

时间:2011-05-27 09:03:16

标签: c++ templates visual-c++ function-pointers

我正在尝试为libcurl编写模板回调函数。但是,当使用指向模板函数实例的指针时,VC ++ 2008和2010不断给我这个错误:

  

template-callback.cpp(27):错误   C2664:'curl_easy_setopt':不能   从'size_t转换参数3   (__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 个答案:

答案 0 :(得分:1)

我在ideone(C ++ 03 with 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
}

问题似乎来自可变参数和函数指针的交互。

注意:在C ++ 0x模式下使用gcc-4.5.1 it works fine

我猜测问题来自于bar(或您的curl_easy_setopt)的重载解析。

问题在于,为了使用省略号,编译器决定如何传递参数:intdoublepointer,......似乎它我们无法自行决定&callback<int>的类型。

当我们使用foo或执行演员表时,它是明确的,因为没有选择。

我怀疑转换问题,但我没有可以深入研究的C ++ 03标准版本。