使用嵌套类的奇怪的enable_if行为(MSVC编译器错误或功能?)
经过相当长的时间调试我的代码后,我使用enable_if将问题的原因追溯到一些意外的模板专业化结果:
以下代码在Visual Studio 2010(和2008)中的DoTest()中失败了断言,而在Visual Studio 2010(和2008)中却没有g++ 3.4.5。 但是,当我从 SomeClass 中删除模板或将 my_condition 移出 SomeClass 范围时,它也可以在 MSVC 中工作。
这段代码是否有问题可以解释这种行为(至少部分地),或者这是 MSVC 编译器中的错误?
(使用此示例代码,对于 boost 和 c++0x stl 版本来说是相同的)
#include <cassert>
#include <boost\utility\enable_if.hpp>
template <class X>
class SomeClass {
public:
template <class T>
struct my_condition {
static const bool value = true;
};
template <class T, class Enable = void>
struct enable_if_tester {
bool operator()() { return false; }
};
template <class T>
struct enable_if_tester<T, typename boost::enable_if< my_condition<T> >::type> {
bool operator()() { return true; }
};
template <class T>
void DoTest() {
enable_if_tester<T> test;
assert( test() );
}
};
int main() {
SomeClass<float>().DoTest<int>();
return 0;
}
当尝试通过将条件移出范围来修复它时,我还注意到这在使用 std::enable_if 时甚至还不够,但至少它适用于 boost::enable_if:
#include <cassert>
//#include <boost\utility\enable_if.hpp>
#include <type_traits>
template <class T, class X>
struct my_condition {
static const bool value = true;
};
template <class X>
class SomeClass {
public:
template <class T, class Enable = void>
struct enable_if_tester {
bool operator()() { return false; }
};
template <class T>
//struct enable_if_tester<T, typename boost::enable_if< my_condition<T, X> >::type> {
struct enable_if_tester<T, typename std::enable_if< my_condition<T, X>::value >::type> {
bool operator()() { return true; }
};
template <class T>
void DoTest() {
enable_if_tester<T> test;
assert( test() );
}
};
int main() {
SomeClass<float>().DoTest<int>();
return 0;
}
我希望有人对此有解释。
After quite some time debugging my code, I tracked down the reason for my problems to some unexpected template specialization results using enable_if:
The following code fails the assertion in DoTest() in Visual Studio 2010 (and 2008), while it doesn't in g++ 3.4.5.
However, when i remove the template from SomeClass or move my_condition out of the scope of SomeClass it works in MSVC, too.
Is there something wrong with this code that would explain this behaviour (at least partially) or is this a bug in the MSVC compiler?
(using this example code it's the same for boost and the c++0x stl version)
#include <cassert>
#include <boost\utility\enable_if.hpp>
template <class X>
class SomeClass {
public:
template <class T>
struct my_condition {
static const bool value = true;
};
template <class T, class Enable = void>
struct enable_if_tester {
bool operator()() { return false; }
};
template <class T>
struct enable_if_tester<T, typename boost::enable_if< my_condition<T> >::type> {
bool operator()() { return true; }
};
template <class T>
void DoTest() {
enable_if_tester<T> test;
assert( test() );
}
};
int main() {
SomeClass<float>().DoTest<int>();
return 0;
}
When trying to fix it by moving the condition out of the scope, i also noticed that this isn't even enough when using std::enable_if, but at least it works with boost::enable_if:
#include <cassert>
//#include <boost\utility\enable_if.hpp>
#include <type_traits>
template <class T, class X>
struct my_condition {
static const bool value = true;
};
template <class X>
class SomeClass {
public:
template <class T, class Enable = void>
struct enable_if_tester {
bool operator()() { return false; }
};
template <class T>
//struct enable_if_tester<T, typename boost::enable_if< my_condition<T, X> >::type> {
struct enable_if_tester<T, typename std::enable_if< my_condition<T, X>::value >::type> {
bool operator()() { return true; }
};
template <class T>
void DoTest() {
enable_if_tester<T> test;
assert( test() );
}
};
int main() {
SomeClass<float>().DoTest<int>();
return 0;
}
I hope someone has an explanation for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的代码一切都很好,只是 VC 有问题。众所周知,模板成员类的部分模板特化存在问题。
Everything is fine with your code, it's just that VC is buggy. It's known to have problems with partial template specialization of template member classes.