Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将函数指针用作模板方法的默认参数时出错_C++_Templates_Namespaces_Function Pointers_Default Arguments - Fatal编程技术网

C++ 将函数指针用作模板方法的默认参数时出错

C++ 将函数指针用作模板方法的默认参数时出错,c++,templates,namespaces,function-pointers,default-arguments,C++,Templates,Namespaces,Function Pointers,Default Arguments,尝试编译此代码时,在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>() {} }

尝试编译此代码时,在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;
}
名称空间栏{
模板void foo();
模板void foo(){}
}
结构A{
无效(*f)();
模板内联void set_func(void(*f)(=bar::foo){this->f=f;}
};
内部主(空){
A A;
a、 set_func();
返回0;
}
当我将
bar::foo
移动到全局名称空间中时,我不再得到错误。谁能解释一下吗


我编辑了上面的代码,以消除对成员函数和模板专门化的一些混淆。我还删除了typedef,它给出了相同错误的更奇怪的版本:
无法将'void(_cdecl*)(void)'转换为'void(_cdecl*)(void)

,因为这显然是编译器本身的一个bug,所以我所能做的就是创建一个解决方案来实现相同的效果

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

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

此问题的另一个解决方法

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
        }
}
typedef void(*FunctionPointer)(int,int);
类模板
{
公众:
模板
静态无效函数(int Arg0,int Arg1)
{
//代码和东西
}
//原始函数-产生编译错误。
//生成-错误C2440:“默认参数”:无法从“重载函数”转换为“函数指针”(VS2012 SP5 x64)
模板
void Original(FunctionPointer Arg=&Template::Function)
{
//代码和东西
}
//变通功能-编译良好。
//默认参数为NULL,并在运行时初始化函数内部的默认参数。
模板
void Original(FunctionPointer Arg=NULL)
{
如果(Arg==NULL)
Arg=&模板::函数;
//代码和东西
}
}

您的编译器已损坏。使用
&bar::foo
可能会有所帮助,因为它删除了对函数指针的隐式转换。将
bar::foo
更改为
&bar::foo
无效错误消息是否详细说明了转换无法进行的原因?是否可以删除typedef并直接指定类型?您是否在MS Connect上提交了错误报告?删除typedef并直接使用
void(*)(
)没有帮助。我将向MS提交一份错误报告,因为这似乎不寻常。我不知道这是否相关,但您正在对
bar::foo
进行显式专门化,这应该在相同的命名空间中完成,例如
namespace bar{template void foo(){}
(由于
bar::foo
语法,我最初认为
bar
是一个类,因此我删除了答案)。