我有一堆在g++下编译得很好的模板化代码,但现在当我尝试在windows下使用Visual C++ 2010构建时,我得到了一堆错误。
我有一组模板函数,用于从Lua代码中获取和设置C++对象中的值。例如,我有这样的模板:
// Class Return type Getter function
template <typename T, typename U, U (T::*Getter)() const>
int luaU_get(lua_State* L)
{
T* obj = luaW_check<T>(L, 1); // Gets userdata from stack and checks if it's of type T
luaU_push(L, (obj->*Getter)()); // Runs the getter function specified in the template, and pushes the
return 1;
}(完整文件可在here中找到)
实例化如下:
static luaL_reg TextArea_MT[] =
{
// Class Return type Getter function
{ "GetCharacterSize", luaU_get<TextArea, unsigned int, &TextArea::GetCharacterSize> },
{ NULL, NULL }
};该getter的签名如下:
unsigned int GetCharacterSize() const;我收到了一堆这样的错误:
2>C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\game\lua\LuaTextArea.cpp(103): error C2440: 'specialization' : cannot convert from 'unsigned int (__thiscall ag::ui::TextArea::* )(void) const' to 'unsigned int *(__thiscall ag::ui::TextArea::* const )(void) const'
2> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
2>C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\game\lua\LuaTextArea.cpp(103): error C2973: 'luaU_get' : invalid template argument 'unsigned int (__thiscall ag::ui::TextArea::* )(void) const'
2> C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\extern\LuaWrapper\LuaWrapperUtil.hpp(147) : see declaration of 'luaU_get'
2>C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\game\lua\LuaTextArea.cpp(103): error C2440: 'specialization' : cannot convert from 'unsigned int (__thiscall ag::ui::TextArea::* )(void) const' to 'unsigned int *ag::ui::TextArea::* const '
2> There is no context in which this conversion is possible
2>C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\game\lua\LuaTextArea.cpp(103): error C2973: 'luaU_get' : invalid template argument 'unsigned int (__thiscall ag::ui::TextArea::* )(void) const'
2> C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\extern\LuaWrapper\LuaWrapperUtil.hpp(131) : see declaration of 'luaU_get'
2>C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\game\lua\LuaTextArea.cpp(103): error C2440: 'specialization' : cannot convert from 'unsigned int (__thiscall ag::ui::TextArea::* )(void) const' to 'unsigned int ag::ui::TextArea::* const '
2> There is no context in which this conversion is possible
2>C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\game\lua\LuaTextArea.cpp(103): error C2973: 'luaU_get' : invalid template argument 'unsigned int (__thiscall ag::ui::TextArea::* )(void) const'
2> C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\extern\LuaWrapper\LuaWrapperUtil.hpp(123) : see declaration of 'luaU_get'
2>C:\Users\Alex\Documents\Visual Studio 2010\Projects\game\dev\src\game\lua\LuaTextArea.cpp(103): error C2440: 'initializing' : cannot convert from 'overloaded-function' to 'lua_CFunction'
2> None of the functions with this name in scope match the target type发布于 2011-12-31 06:43:14
这是VC++中的编译器错误。以下代码有效:
#include <iostream>
struct TextArea
{
unsigned GetCharacterSize() const { return 0; }
};
template<typename T, typename U, U (T::*)() const>
int foo()
{
return 1;
}
template<typename T, typename U, U* (T::*)() const>
int foo()
{
return 2;
}
int main()
{
std::cout << foo<TextArea, unsigned, &TextArea::GetCharacterSize>() << '\n';
}并使用GCC 4.3.4、GCC 4.5.1和Comeau 4.3.10.1 Beta2 (无链接)进行编译,但在使用VC++ 2010 SP1时生成以下错误:
错误C2668:
'foo':对重载函数的调用不明确
EDIT:作为一种变通方法,它很难看,但我能想到的唯一一件事就是使用额外的间接层,这样就不会涉及重载:
#include <iostream>
struct WithPointer
{
unsigned* GetCharacterSize() const { return nullptr; }
};
struct WithoutPointer
{
unsigned GetCharacterSize() const { return 0u; }
};
template<bool UsePointerImplB>
struct kludge
{
template<typename T, typename U, U (T::*Getter)() const>
static int foo() { return 1; }
};
template<>
struct kludge<true>
{
template<typename T, typename U, U* (T::*Getter)() const>
static int foo() { return 2; }
};
int main()
{
std::cout
<< kludge<false>::foo<WithoutPointer, unsigned, &WithoutPointer::GetCharacterSize>() << '\n'
<< kludge<true>::foo<WithPointer, unsigned, &WithPointer::GetCharacterSize>() << '\n';
}实际上,这与给每个重载一个不同的名称没有什么不同。
发布于 2011-12-31 08:25:49
如果您可以强制用户选择函数的实际返回类型,则可以使用以下方法。也许,它会对你有用:
#include <iostream>
struct FooBar
{
int Foo( void ) const
{
std::cout << "FooBar::Foo()" << std::endl;
return ( 0 );
}
int * Bar( void ) const
{
std::cout << "FooBar::Bar()" << std::endl;
return ( 0 );
}
};
template< typename P00, typename P01, P01(P00::*p02)( void ) const >
void Call()
{
P00 lT;
( lT.*p02 )();
}
int main( void )
{
Call< FooBar, int, &FooBar::Foo > ();
Call< FooBar, int*, &FooBar::Bar > ();
return( 0 );
}程序输出:
FooBar::Foo()
FooBar::Bar()https://stackoverflow.com/questions/8684583
复制相似问题