我有几个具有以下继承关系的类:
template <typename ID_t>
class Identifiable {
public:
virtual ID_t unique_ID() const {
return 0;
}
};
template <typename DerivedName>
class SomeBase : public Identifiable<typename DerivedName::ID_t> {
public:
virtual DerivedName & instance() = 0;
};
template <uint16_t SomeParam = 5>
class SomeDerived : public SomeBase<SomeDerived<SomeParam>> {
public:
using ID_t = uint16_t;
SomeDerived & instance() override {
return *this;
}
ID_t unique_ID() const override {
return SomeParam;
}
};
int main() {
std::cout << "Hello, World!\n";
SomeDerived<> instance;
std::cout << std::to_string(instance.unique_ID()) << std::endl;
}
但是这并没有用&#34编译;在类SomeDerived&#34;中没有名为ID_t的类型。在SomeBase
声明中。即使接缝很明显,有没有办法在没有这个检查的情况下强制编译?或者修改它而不将ID_t
作为另一个模板参数传递?
以下是沙箱的链接:cpp.sh/57ox6
答案 0 :(得分:0)
您缺少来自Identifiable
的类型别名:
template <typename ID>
class Identifiable {
public:
using ID_t = ID;
virtual ID_t unique_ID() const {
return 0;
}
};
答案 1 :(得分:0)
问题是您在定义之前尝试使用SomeDerived::ID_t
。
你可以稍微重构一下这些课程,让它适合你。
#include <iostream>
#include <string>
template <typename ID>
class Identifiable
{
public:
using ID_t = ID;
virtual ID_t unique_ID() const {
return 0;
}
};
template <typename DerivedName>
class SomeBase
{
public:
virtual DerivedName & instance() = 0;
};
template <uint16_t SomeParam = 5>
class SomeDerived : public Identifiable<uint16_t>,
public SomeBase<SomeDerived<SomeParam>>
{
public:
SomeDerived & instance() override {
return *this;
}
ID_t unique_ID() const override {
return SomeParam;
}
};
int main()
{
std::cout << "Hello, World!\n";
SomeDerived<> instance1;
std::cout << std::to_string(instance1.unique_ID()) << std::endl;
SomeDerived<20> instance2;
std::cout << std::to_string(instance2.unique_ID()) << std::endl;
}
输出:
Hello, World!
5
20
答案 2 :(得分:0)
即使接缝很明显,有没有办法在没有这个检查的情况下强制编译?或者修复它而不将ID_t作为另一个模板参数传递?
如果没有此检查强制编译,这不是问题。你想要做的事情违反了语言的规则,就是这样。因此,它是无法编译的格式错误的代码
换句话说,在SomeBase
范围内,您尝试使用未完全定义的类型(SomeDerived
)。因此,您不能指望DerivedName::ID_t
在那里。并且你不能期望能够告诉你的编译器 - ehy,dude,忽略C ++标准并编译它,无论它是什么。
@ R.Sahu发布了his answer的有效解决方法,也许是您可以得到的最短,最有效的解决方案。
另一种选择是使用特征,如下例所示:
#include<cstdint>
#include<iostream>
template <typename T>
struct Identifiable {
using ID_t = T;
virtual ID_t unique_ID() const {
return 0;
}
};
template<typename>
struct SomeTraits;
template <typename DerivedName>
struct SomeBase : public Identifiable<typename SomeTraits<DerivedName>::ID_t> {
virtual DerivedName & instance() = 0;
};
template <uint16_t SomeParam = 5>
struct SomeDerived;
template<uint16_t SomeParam>
struct SomeTraits<SomeDerived<SomeParam>> {
using ID_t = uint16_t;
};
template <uint16_t SomeParam>
struct SomeDerived : public SomeBase<SomeDerived<SomeParam>> {
using ID_t = typename SomeBase<SomeDerived<SomeParam>>::ID_t;
SomeDerived & instance() override {
return *this;
}
ID_t unique_ID() const override {
return SomeParam;
}
};
int main() {
std::cout << "Hello, World!\n";
SomeDerived<> instance;
std::cout << std::to_string(instance.unique_ID()) << std::endl;
}