Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.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++ 如何解决此问题<;未解析的重载函数类型>;使用std::函数时出错?_C++_C++11 - Fatal编程技术网

C++ 如何解决此问题<;未解析的重载函数类型>;使用std::函数时出错?

C++ 如何解决此问题<;未解析的重载函数类型>;使用std::函数时出错?,c++,c++11,C++,C++11,在下面的(工作)代码示例中,模板化register_enum()函数用于迭代枚举,并调用用户提供的回调函数将枚举值转换为c字符串。所有枚举都是在一个类中定义的,枚举到字符串的转换是通过静态到字符串(enum)函数完成的。当一个类(如下面的着色器类)具有多个枚举并对应重载到_cstring(enum)函数时,编译器无法确定传递到register _enum()的正确的to _cstring()函数。我觉得代码解释得比我能解释的好 #include <functional> #inclu

在下面的(工作)代码示例中,模板化register_enum()函数用于迭代枚举,并调用用户提供的回调函数将枚举值转换为c字符串。所有枚举都是在一个类中定义的,枚举到字符串的转换是通过静态到字符串(enum)函数完成的。当一个类(如下面的着色器类)具有多个枚举并对应重载到_cstring(enum)函数时,编译器无法确定传递到register _enum()的正确的to _cstring()函数。我觉得代码解释得比我能解释的好

#include <functional>
#include <iostream>

// Actual code uses Lua, but for simplification
// I'll hide it in this example.
typedef void lua_State;

class widget
{
    public:
        enum class TYPE
        {
            BEGIN = 0,
            WINDOW = BEGIN,
            BUTTON,
            SCROLL,
            PROGRESS,
            END
        };

        static const char *to_cstring( const TYPE value )
        {
            switch ( value )
            {
                case TYPE::WINDOW: return "window";
                case TYPE::BUTTON: return "button";
                case TYPE::SCROLL: return "scroll";
                case TYPE::PROGRESS: return "progress";
                default: break;
            }
            return nullptr;
        }
};

class shader
{
    public:
        enum class FUNC
        {
            BEGIN = 0,
            TRANSLATE = BEGIN,
            ROTATE,
            SCALE,
            COLOR,
            COORD,
            END
        };

        enum class WAVEFORM
        {
            BEGIN = 0,
            SINE = BEGIN,
            SQUARE,
            TRIANGLE,
            LINEAR,
            NOISE,
            END
        };

        static const char *to_cstring( const FUNC value )
        {
            switch ( value )
            {
                case FUNC::TRANSLATE: return "translate";
                case FUNC::ROTATE: return "rotate";
                case FUNC::SCALE: return "scale";
                case FUNC::COLOR: return "color";
                case FUNC::COORD: return "coord";
                default: break;
            }
            return nullptr;
        }

        static const char *to_cstring( const WAVEFORM value )
        {
            switch ( value )
            {
                case WAVEFORM::SINE: return "sine";
                case WAVEFORM::SQUARE: return "square";
                case WAVEFORM::TRIANGLE: return "triangle";
                case WAVEFORM::LINEAR: return "linear";
                case WAVEFORM::NOISE: return "noise";
                default: break;
            }
            return nullptr;
        }
};

// Increment an enum value.
// My compiler (g++ 4.6) doesn't support type_traits for enumerations, so
// here I just static_cast the enum value to int... Something to be fixed
// later...
template < class E >
E &enum_increment( E &value )
{
    return value = ( value == E::END ) ? E::BEGIN : E( static_cast<int>( value ) + 1 );
}

widget::TYPE &operator++( widget::TYPE &e )
{
    return enum_increment< widget::TYPE >( e );
}

shader::FUNC &operator++( shader::FUNC &e )
{
    return enum_increment< shader::FUNC >( e );
}

shader::WAVEFORM &operator++( shader::WAVEFORM &e )
{
    return enum_increment< shader::WAVEFORM >( e );
}


// Register the enumeration with Lua
template< class E >
void register_enum( lua_State *L, const char *table_name, std::function< const char*( E ) > to_cstring )
{
    (void)L; // Not used in this example.
    // Actual code creates a table in Lua and sets table[ to_cstring( i ) ] = i
    for ( auto i = E::BEGIN; i < E::END; ++i )
    {
        // For now, assume to_cstring can't return nullptr...
        const char *key = to_cstring( i );
        const int value = static_cast<int>(i);
        std::cout << table_name << "." << key << " = " << value << std::endl;
    }
}

int main( int argc, char **argv )
{
    (void)argc; (void)argv;

    lua_State *L = nullptr;

    // Only one to_cstring function in widget class so this works...
    register_enum< widget::TYPE >( L, "widgets", widget::to_cstring );

    // ... but these don't know which to_cstring to use.
    register_enum< shader::FUNC >( L, "functions", shader::to_cstring );
    //register_enum< shader::WAVEFORM >( L, "waveforms", shader::to_cstring );

    return 0;
}
#包括
#包括
//实际代码使用Lua,但为了简化
//我将在本例中隐藏它。
类型定义无效lua_状态;
类小部件
{
公众:
枚举类类型
{
开始=0,
窗口=开始,
按钮
纸卷
进步,
结束
};
静态常量字符*到字符串(常量类型值)
{
开关(值)
{
案例类型::窗口:返回“窗口”;
案例类型::按钮:返回“按钮”;
案例类型::滚动:返回“滚动”;
案例类型::进度:返回“进度”;
默认:中断;
}
返回空ptr;
}
};
类着色器
{
公众:
枚举类函数
{
开始=0,
翻译=开始,
旋转
规模
颜色
库德,
结束
};
枚举类波形
{
开始=0,
正弦=开始,
广场
三角形,
线性的
噪音
结束
};
静态常量字符*到字符串(常量函数值)
{
开关(值)
{
case FUNC::TRANSLATE:返回“TRANSLATE”;
case FUNC::ROTATE:返回“ROTATE”;
case FUNC::SCALE:返回“SCALE”;
case FUNC::COLOR:返回“COLOR”;
case FUNC::COORD:返回“COORD”;
默认:中断;
}
返回空ptr;
}
静态常量字符*到字符串(常量波形值)
{
开关(值)
{
案例波形::正弦:返回“正弦”;
案例波形::SQUARE:返回“SQUARE”;
案例波形::三角形:返回“三角形”;
案例波形::线性:返回“线性”;
案例波形::噪声:返回“噪声”;
默认:中断;
}
返回空ptr;
}
};
//递增枚举值。
//我的编译器(g++4.6)不支持枚举的类型_特征,因此
//这里我只是将枚举值强制转换为int。。。需要修理的东西
//后来。。。
模板
E和枚举增量(E和值)
{
返回值=(值==E::END)?E::BEGIN:E(静态_转换(值)+1);
}
widget::TYPE&operator++(widget::TYPE&e)
{
返回enum_increment(e);
}
着色器::FUNC&operator++(着色器::FUNC&e)
{
返回enum_increment(e);
}
着色器::波形和运算符++(着色器::波形和e)
{
返回enum_增量(e);
}
//向Lua注册枚举
模板
无效寄存器枚举(lua_State*L,const char*表名,std::functionto_cstring)
{
(void)L;//本例中未使用。
//实际代码在Lua中创建一个表,并将表[to_cstring(i)]=i设置为
对于(自动i=E::BEGIN;istd::cout错误告诉您有两种可能的重载可供使用,编译器无法为您做出决定。另一方面,您可以通过使用强制转换来确定使用哪种重载:

typedef const char *(*func_ptr)( shader::FUNC );
register_enum< shader::FUNC >( L, "functions", (func_ptr)shader::to_cstring );
typedef const char*(*func_ptr)(着色器::func);
将_enum(L,“functions”,(FUNC_ptr)shader::注册到_cstring);
或不带typedef(在较难阅读的单行中):

register\u enum(L,“函数”,
(const char*(*)(shader::FUNC))shader::to_cstring);
*请注意,在函数签名中,顶级的
const
将被删除


下一个问题是编译器为什么没有自己找到合适的重载?问题是在调用
register\u enum
时传递了枚举的类型,并确定
std::function
的类型为
std::function
,但是
std::function
有一个模板构造函数,在试图推断构造函数的参数类型之前,编译器必须知道要使用哪个重载。

我想说的是,在这种情况下,如果编译器无法在这两个重载之间做出决定,应该重命名其中一个!这将防止进一步的错误函数的用法不明确

typedef const char *(*func_ptr)( shader::FUNC );
register_enum< shader::FUNC >( L, "functions", (func_ptr)shader::to_cstring );
register_enum< shader::FUNC >( L, "functions", 
             (const char *(*)( shader::FUNC ))shader::to_cstring );