visual c++ static polymorphism (CRTP) 在评估"静态 constexpr&



我需要访问一个static constexpr,我放在一起的一个解决方案适用于gcc(实时示例),但不适用于vc ++(实时示例)。

代码如下:

template<class Drvd>
class Base
{
public:
static constexpr bool val = Drvd::val;
};
class Derived : public Base<Derived>
{
friend class Base;
private:
static constexpr bool val = true;
};
int main()
{
std::cout << Derived::Base::val << std::endl;
}

所以这是 vc++ 的一个错误,但任何人都知道如何以 vc++ 不会抱怨的不同方式实现Base中定义为Drvdvalval

编辑:请注意,结果与变体相同:friend class Base<Derived>;而不是friend class Base;

您可以使用一种方法:

#include <iostream>
template<class Drvd>
class Base
{
public:
static constexpr bool val() { return Drvd::val;  }
};
class Derived : public Base<Derived>
{
friend class Base<Derived>;
private:
static constexpr bool val = true;
};
int main()
{
std::cout << Derived::Base::val() << std::endl;
}

现场示例:https://rextester.com/IHR24393

你的问题不是私有/朋友声明(即使代码无法编译 "val"是公开的),你的问题是在实例化期间

static constexpr bool val = Drvd::val

Drvd仍然是不完整的类型。 请参阅下面的问题/答案,了解如何使用特征类解决此问题。

C++静态多态性 (CRTP) 并使用派生类中的 typedef

附言事实上,我只是将您的问题标记为重复

根据@David,问题与Face不完整有关,因为它在完成Face的定义之前进入Base

但是,@David链接到的解决方案有点旧,错过了一些我们可以利用的技巧。也就是说,@m.s. 向我们展示了static constexpr函数很好 - 也是基于我自己的实验 - 我们真的只需要处理static constexpr变量的特殊情况,也许还有从Derived访问的类型。

下面的(实时示例)展示了如何解决这个问题,同时将每个类封装到它自己的 h 文件中,使其更干净:

#include <iostream>
// Begin: h-file of Base
template<class Drvd>
class ConstValue;
template<class Drvd>
class Base
{
public:
static constexpr bool val = ConstValue<Drvd>::val;
};
// End: h-file of Base
// Begin: h-file of Derived
class Derived;
template<>
class ConstValue<Derived>
{
public:
static constexpr bool val = true;
};
class Derived : public Base<Derived>
{
friend class Base<Derived>;
private:
static constexpr bool val = true; // optional
};
// End: h-file of Derived
// Main
int main()
{
std::cout << Derived::Base::val << std::endl;
}

一般的想法是,对于Base需要从Derived访问的每个constexpr,我们可以创建一个封装变量的类,然后为每个使用BaseDerived重载该类。

最新更新