【问题标题】:Error using function pointer as default argument to template method使用函数指针作为模板方法的默认参数时出错
【发布时间】:2023-03-13 15:04:01
【问题描述】:

当我尝试编译此代码时,我在 Visual Studio 2012 中收到以下编译器错误:

error C2440: 'default argument' : cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'

我的代码:

namespace bar {
    template<typename T> void foo();
    template<> void foo<int>() {}
}

struct A {
    void(*f)();

    template<typename T> inline void set_func(void(*f)()=bar::foo<T>) {this->f=f;}
};

int main(void) {
    A a;
    a.set_func<int>();
    return 0;
}

当我将 bar::foo 移动到全局命名空间时,我不再收到错误消息。谁能解释一下?

我已经编辑了上面的代码,以消除对成员函数和模板专业化的一些混淆。我还删除了 typedef,它给出了相同错误的更奇怪的版本:cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'

【问题讨论】:

  • 你的编译器坏了。也许使用&amp;bar::foo&lt;T&gt; 会有所帮助,因为它消除了到函数指针的隐式转换。
  • bar::foo&lt;T&gt; 更改为&amp;bar::foo&lt;T&gt; 无效
  • 错误信息是否更多地说明了为什么无法进行转换?您可以删除 typedef 并直接指定类型吗?您是否提交过关于 MS Connect 的错误报告?
  • 删除 typedef 并直接使用 void(*)() 没有帮助。我将向 MS 提交错误报告,因为这似乎很不寻常。
  • 我不知道这是否相关,但您正在对 bar::foo 进行明确的特化,这应该在同一个命名空间中完成,例如namespace bar{template&lt;&gt; void foo&lt;int&gt;() {}} (由于bar::foo 语法,我最初认为bar 是一个类,因此我删除了答案)。

标签: c++ templates namespaces function-pointers default-arguments


【解决方案1】:

因为这显然是编译器本身的一个错误,我所能做的就是创建一个解决方法来达到相同的效果。

我删除了默认参数并使用了如下重载方法:

template<typename T> inline void set_func() {this->f=bar::foo<T>;}
template<typename T> inline void set_func(void(*f)()) {this->f=f;}

【讨论】:

    【解决方案2】:

    解决此问题的另一种方法。

    typedef void (*FunctionPointer)(int, int);
    
    class Template
    {
        public:
            template<typename Type>
            static void Function(int Arg0, int Arg1)
            {
                // Code and Stuff
            }
    
            // ORIGINAL FUNCTION - Produces compile errors.
            // Produces - error C2440: 'default argument' : cannot convert from 'overloaded-function' to 'FunctionPointer' (VS2012 SP5 x64)
            template<typename Type>    
            void Original(FunctionPointer Arg = &Template::Function<Type>)
            {
                // Code and Stuff
            }
    
            // WORKAROUND FUNCTION - Compiles fine.
            // Default Arg parameter to NULL and initialize default parameter inside function on runtime.
            template<typename Type>    
            void Original(FunctionPointer Arg = NULL)
            {
                if (Arg == NULL)
                    Arg = &Template::Function<Type>;
    
                // Code and Stuff
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-25
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多