MSVC C ++编译器限制-在CRTP下无法使用特性

时间:2019-05-21 18:30:11

标签: c++ traits crtp

我对MSVC 2017和2019有一个关于此限制的问题:我想在编译时知道某个CRTP模板“派生”类是否具有特定功能。

这是我的班级特质评估:

nullptr

我用一些简单的类对其进行了测试:

NULL

我得到了预期的结果。如预期的那样,此测试的评估结果为:1 1 0 1 0 1 1:template <typename T> class function_exists_trait { private: template <typename U> static auto test_todo(U * u) -> decltype(&U::exists) {} static auto test_todo(...) -> std::false_type {} public: static constexpr bool value{ !std::is_same<decltype(test_todo(static_cast<T*>(nullptr))), std::false_type>::value }; };

对于以下CRTP简单实现(0 1 1 1),我得到了预期的结果:

struct t1 { void exists() {} };
struct t2 { void exists() {} };
struct t3 {};
struct t4 : public t1 {};
struct t5 : public t3 {};
struct t6 : public t3 { void exists() {} };

问题是这样的:当尝试评估CRTP基类内部的特征时,什么都没有起作用,我也不明白为什么。

cout << function_exists_trait<t1>::value << " " << ...

以下代码给出了此结果:0 0-0 0-0 0-0 0

template <typename t> struct u1 {};
struct crtp1 : public u1<crtp1> { void exists() {} };
template <typename t> struct u2 { void exists() {} };
struct crtp2 : public u2<crtp2> {};

cout << function_exists_trait<u1<int>>::value << " "
     << function_exists_trait<crtp1>::value << " "
     << function_exists_trait<u2<int>>::value << " "
     << function_exists_trait<crtp2>::value << endl;

我已经发布了这个问题,以为我做错了什么,但这似乎是MSVC的问题。感谢P.W.他向我展示了这似乎是MSVC的局限性。他向我展示了完全相同的代码在gcc下给出了此结果:0 0-1 1-1 1-1 1

有人对如何解决这个问题有任何建议。 MSVC可能有一个显而易见的解决方案来触发预期的结果。或者只是在MSVC下实现相同目标的另一种方法。

1 个答案:

答案 0 :(得分:1)

如博格丹所知,这是一种可行的替代方法:

template <typename t> struct u6 {
    void exists() {}
    static constexpr bool value() { return function_exists_trait<t>::value; }
};
struct crtp6 : public u6<crtp6> {
    void exists() {}
};

谢谢大家!