Reg*_*gus 3 c++ inheritance templates class-template c++20
考虑这个简单的类派生自std::variant:
#include <string>
#include <variant>
class my_variant : public std::variant<int, std::string>
{
using variant::variant;
public:
std::string foo()
{
return "foo";
}
};
Run Code Online (Sandbox Code Playgroud)
请注意,我故意添加using variant:variant以便在派生类中公开基类的构造函数。如果不这样做,类的实例将无法 在没有大量重新定义的情况下my_variant工作。operator=这编译得很好。
现在让我们开始逐步将其变成模板。
template <typename TChr>
class my_variant : public std::variant<int, std::string>
{
using variant::variant;
public:
// Changed to templated return type, compiles fine
std::basic_string<TChr> foo()
{
return "foo";
}
};
Run Code Online (Sandbox Code Playgroud)
在这里,唯一的变化是我们在方法中使用了模板参数foo()。一切仍然编译良好。
现在这个:
template <typename TChr>
class my_variant : // Changed to templated base class
public std::variant<int, std::basic_string<TChr>>
{
// Now this line won't compile !!
using variant::variant;
public:
std::basic_string<TChr> foo()
{
return "foo";
}
};
Run Code Online (Sandbox Code Playgroud)
一旦我使用模板参数来描述基类,我就会收到以下编译器错误:
'variant': is not a class or namespace name
Run Code Online (Sandbox Code Playgroud)
对于这一行:using variant::variant;
我不完全理解为什么这个特定的变化会导致问题。到目前为止,我在想,也许using variant::variant不指定其模板签名是一个问题,所以我尝试了这个:
template <typename TChr>
class my_variant :
public std::variant<int, std::basic_string<TChr>>
{
// Added templating here, still fails with the same error message.
using variant<int, std::basic_string<TChr>>::variant;
public:
std::basic_string<TChr> foo()
{
return "";
}
};
Run Code Online (Sandbox Code Playgroud)
这样做会产生相同的错误消息,所以我一定做错了什么。
编译器是MSVC 2022,C++20模式。
[...]所以我一定做错了什么!
由于在最后一个中 my_variant,父级std::variant依赖于类模板参数,因此您还需要来自正确父级的构造函数
template <typename TChr>
class my_variant : public std::variant<int, std::basic_string<TChr>>
{
using std::variant<int, std::basic_string<TChr>>::variant;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
public:
std::basic_string<TChr> foo()
{
return "foo";
}
};
Run Code Online (Sandbox Code Playgroud)
已经提到过,也请阅读此处,了解有关您的方法的更多信息: