检测类是否具有重载函数在 Comeau 编译器上失败
我正在尝试使用 SFINAE 来检测类是否具有采用某种类型的重载成员函数。我的代码似乎可以在 Visual Studio 和 GCC 中正常工作,但无法使用 Comeau 在线编译器进行编译。
这是我正在使用的代码:
#include <stdio.h>
//Comeau doesnt' have boost, so define our own enable_if_c
template<bool value> struct enable_if_c { typedef void type; };
template<> struct enable_if_c< false > {};
//Class that has the overloaded member function
class TestClass
{
public:
void Func(float value) { printf( "%f\n", value ); }
void Func(int value) { printf( "%i\n", value ); }
};
//Struct to detect if TestClass has an overloaded member function for type T
template<typename T>
struct HasFunc
{
template<typename U, void (TestClass::*)( U )> struct SFINAE {};
template<typename U> static char Test(SFINAE<U, &TestClass::Func>*);
template<typename U> static int Test(...);
static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};
//Use enable_if_c to only allow the function call if TestClass has a valid overload for T
template<typename T> typename enable_if_c<HasFunc<T>::Has>::type CallFunc(TestClass &test, T value) { test.Func( value ); }
int main()
{
float value1 = 0.0f;
int value2 = 0;
TestClass testClass;
CallFunc( testClass, value1 ); //Should call TestClass::Func( float )
CallFunc( testClass, value2 ); //Should call TestClass::Func( int )
}
错误消息是:没有函数模板“CallFunc”的实例与参数列表匹配。看起来 HasFunc::Has 对于 int 和 float 来说是 false,而它应该是 true。
这是 Comeau 编译器中的错误吗?我是否做了一些不标准的事情?如果是这样,我需要做什么来解决它?
更新
我想现在的问题是,如果这是一个错误,我可以做些什么来解决它吗?我尝试在 &TestClass::Func 上使用 static_cast,但要么这是不可能的,要么我没有得到正确的语法,因为我无法编译它。
如果这不是解决方案,我是否可以对 TestClass 或 HasFunc 进行任何修改以解决该问题?
I'm trying to use SFINAE to detect if a class has an overloaded member function that takes a certain type. The code I have seems to work correctly in Visual Studio and GCC, but does not compile using the Comeau online compiler.
Here is the code I'm using:
#include <stdio.h>
//Comeau doesnt' have boost, so define our own enable_if_c
template<bool value> struct enable_if_c { typedef void type; };
template<> struct enable_if_c< false > {};
//Class that has the overloaded member function
class TestClass
{
public:
void Func(float value) { printf( "%f\n", value ); }
void Func(int value) { printf( "%i\n", value ); }
};
//Struct to detect if TestClass has an overloaded member function for type T
template<typename T>
struct HasFunc
{
template<typename U, void (TestClass::*)( U )> struct SFINAE {};
template<typename U> static char Test(SFINAE<U, &TestClass::Func>*);
template<typename U> static int Test(...);
static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};
//Use enable_if_c to only allow the function call if TestClass has a valid overload for T
template<typename T> typename enable_if_c<HasFunc<T>::Has>::type CallFunc(TestClass &test, T value) { test.Func( value ); }
int main()
{
float value1 = 0.0f;
int value2 = 0;
TestClass testClass;
CallFunc( testClass, value1 ); //Should call TestClass::Func( float )
CallFunc( testClass, value2 ); //Should call TestClass::Func( int )
}
The error message is: no instance of function template "CallFunc" matches the argument list. It seems that HasFunc::Has is false for int and float when it should be true.
Is this a bug in the Comeau compiler? Am I doing something that's not standard? And if so, what do I need to do to fix it?
Update
I guess the question now becomes, if this is a bug, is there anything I can do to work around it? I tried using a static_cast on &TestClass::Func, but either that isn't possible or I didn't get the syntax right because I couldn't get it to compile.
If that's not a solution, is there any modifications I can make either to TestClass or HasFunc in order to work around the issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我怀疑问题在于,当 TestClass 重载 Func 时,Comeau 编译器无法消除 &TestClass::Func 的歧义,即使它应该这样做。
I suspect the problem is that as TestClass overloads Func and the Comeau compiler is unable to disambiguate &TestClass::Func, even it it should.