我需要访问一个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
中定义为Drvd
中val
值val
?
编辑:请注意,结果与变体相同: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
,我们可以创建一个封装变量的类,然后为每个使用Base
的Derived
重载该类。