使用嵌套类的奇怪的enable_if行为(MSVC编译器错误或功能?)

发布于 2024-09-09 02:09:00 字数 2150 浏览 7 评论 0原文

经过相当长的时间调试我的代码后,我使用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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我鬧 2024-09-16 02:09:00

你的代码一切都很好,只是 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文