![](/img/trans.png)
[英]std::thread <unresolved overloaded function type> error
[英]How do I resolve this <unresolved overloaded function type> error when using std::function?
在以下(工作)代码示例中,模板化的 register_enum() function 用于迭代枚举并调用用户提供的回调以将枚举值转换为 c 字符串。 所有枚举均在class中定义,并使用static TO_CSTRING(ENUM)function进行枚举转换。无法确定传递给 register_enum() 的正确 to_cstring() function。 我认为代码比我能解释得更好......
#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;
}
编译器 output:
$ g++ -std=c++0x -Wall -Wextra -pedantic test.cpp -o test && ./test
test.cpp: In function ‘int main(int, char**)’:
test.cpp:140:69: error: no matching function for call to ‘register_enum(lua_State*&, const char [10], <unresolved overloaded function type>)’
test.cpp:140:69: note: candidate is:
test.cpp:117:7: note: template<class E> void register_enum(lua_State*, const char*, std::function<const char*(E)>)
如何将正确的 to_cstring function 传递给 register_enum()? 我意识到我可以重命名各个 to_cstring() 函数,但我想尽可能避免这种情况。 也许我的设计很臭,你可以推荐一个更好的方法。
我的问题看起来类似于Calling overloaded function using templates (unresolved overloaded function type compiler error)和如何获取重载成员的地址 function? 但到目前为止,我无法将该信息应用于我的具体问题。
该错误告诉您有两个潜在的重载可以使用,编译器无法为您决定。 另一方面,您可以通过强制转换来确定使用哪个:
typedef const char *(*func_ptr)( shader::FUNC );
register_enum< shader::FUNC >( L, "functions", (func_ptr)shader::to_cstring );
或者没有 typedef(在更难阅读的一行中):
register_enum< shader::FUNC >( L, "functions",
(const char *(*)( shader::FUNC ))shader::to_cstring );
*请注意,在 function 签名中,顶级const
被删除。
下一个问题是为什么编译器没有自己找到合适的重载? 问题在于,在对register_enum
的调用中,您传递了枚举的类型,这决定了std::function
的类型为std::function< const char* ( shader::FUNC ) >
,但是std::function
有一个模板化的构造函数,在尝试推断构造函数的参数类型之前,编译器必须知道您要使用哪个重载。
我会说,在这种情况下,如果编译器无法在两个重载之间做出决定,您应该重命名其中一个。 这将防止函数的进一步模糊使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.