c ++静态多态性(CRTP)在评估`static constexpr`时导致类型不完整
c++ static polymorphism (CRTP) Resulting in incomplete type when evaluating a `static constexpr`
我需要访问 static constexpr
并且我将一个解决方案与 gcc (live example) but not with vc++ (live example) 结合使用。
代码如下:
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++ 的一个错误,但是任何人都知道如何实现 Base
中定义的 val
作为 val
中的值Drvd
vc++ 不会抱怨的另一种方式?
编辑:
请注意,结果与变体相同: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;
}
你的问题不是 private/friend 声明(即使
"val" 是 public),你的问题是在实例化
期间
static constexpr bool val = Drvd::val
Drvd 仍然是不完整的类型。
请参阅下文 question/answer 了解如何使用特征 类.
解决此问题
C++ static polymorphism (CRTP) and using typedefs from derived classes
P.S。事实上,我只是将您的问题标记为重复
Per @David,问题与 Face
不完整有关,因为它在完成 Face
.
的定义之前进入 Base
但是,@David 链接到的解决方案有点旧,并且遗漏了一些我们可以利用的技巧。即,@m.s。向我们展示了 static constexpr
函数是好的 - 并且也是基于我自己的实验 - 我们真的只需要处理 static constexpr
变量的这种特殊情况,也许还有从 Derived
访问的类型。
以下 (live example) 展示了如何解决这个问题,同时将每个 class 封装到它自己的 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
,我们可以创建一个封装变量的单个 class,然后为每个使用 Base
.
的 Derived
重载 class
我需要访问 static constexpr
并且我将一个解决方案与 gcc (live example) but not with vc++ (live example) 结合使用。
代码如下:
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++ 的一个错误,但是任何人都知道如何实现 Base
中定义的 val
作为 val
中的值Drvd
vc++ 不会抱怨的另一种方式?
编辑:
请注意,结果与变体相同: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;
}
你的问题不是 private/friend 声明(即使 "val" 是 public),你的问题是在实例化
期间static constexpr bool val = Drvd::val
Drvd 仍然是不完整的类型。 请参阅下文 question/answer 了解如何使用特征 类.
解决此问题C++ static polymorphism (CRTP) and using typedefs from derived classes
P.S。事实上,我只是将您的问题标记为重复
Per @David,问题与 Face
不完整有关,因为它在完成 Face
.
Base
但是,@David 链接到的解决方案有点旧,并且遗漏了一些我们可以利用的技巧。即,@m.s。向我们展示了 static constexpr
函数是好的 - 并且也是基于我自己的实验 - 我们真的只需要处理 static constexpr
变量的这种特殊情况,也许还有从 Derived
访问的类型。
以下 (live example) 展示了如何解决这个问题,同时将每个 class 封装到它自己的 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
,我们可以创建一个封装变量的单个 class,然后为每个使用 Base
.
Derived
重载 class