我对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下实现相同目标的另一种方法。
答案 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() {}
};
谢谢大家!