【问题标题】:how to use an interface to force a generic datatype from a template in C++?如何使用接口从 C++ 中的模板强制使用通用数据类型?
【发布时间】:2020-04-20 12:38:04
【问题描述】:

早上好,我已经搜索了一些东西,但找不到答案。我正在创建一个泛型类,其想法是泛型数据类型(类型名 T)应该来自一个接口:

这是界面:

template<typename T> class iDataType{

public:

   virtual bool writeOnFile(std::fstream& theFile,T& data) = 0;
   virtual T readOnFile(std::fstream& theFile) = 0;

};

这就是我正在“尝试”做的事情:

template <typename T : public iDataType> class Database{};

感谢您抽出宝贵时间。

【问题讨论】:

  • 你能用C++20吗?
  • 问题可能会被简化。但是在这种情况下,基类取决于类型,并且在它们之上没有公共基类——所以你没有得到一些公共基类,而且基类没有实现任何东西——所以你没有得到一些常见的实现,基本限制没有强加 T 具有您想要的成员函数和您想要的签名的限制那么有用。

标签: c++ templates interface


【解决方案1】:

您可以使用static_assert 在编译时条件下断言,还有std::is_base_of

所以解决办法是:

template <typename T> class Database{
   static_assert(std::is_base_of<iDataType<T>, T>::value, "should be derived from iDataType");
};

请注意,该解决方案适用于 C++11,对于更高版本的 C++ 标准,您可以使用 std::is_base_of_v 和简洁的 static_assert(不带字符串文字参数)。

【讨论】:

  • std::is_base_of 回答T 是否继承自iDataType&lt;T&gt;,但不回答T* 是否可以用作iDataType&lt;T&gt;*(它不回答是否公开继承或明确继承)。
【解决方案2】:

在问题的有限上下文中T 派生自iDataType&lt;T&gt; 的要求似乎没有增加价值。但是,要回答我解释的问题,您想要实现的属性是:

std::is_convertible_v<T*, iDataType<T>*>

std::is_base_of 具有误导性,因为它会回答 T 是否具有 iDataType&lt;T&gt; 的基数,但该语言要求 T&amp; 用作 iDataType&lt;T&gt;&amp; 的公共明确基数。所以,在 C++ 中,当你想知道某个东西是否有一个基类作为接口时,std::is_base_of 是错误的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-09
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多