【问题标题】:CString Inheritance字符串继承
【发布时间】:2021-07-02 10:30:37
【问题描述】:

如果CStringT继承自CSimpleStringT并且CSimpleStringT的类定义如下,根据CSimpleString Documentation

template<typename BaseType>
class CSimpleStringT

CSimpleStringT 如何有两个模板参数?它们是否都具有相同的BaseType 参数,例如template&lt;typename BaseType, class BaseType&gt; class CSimpleStringT

来自CStringT Documentation

template<typename BaseType, class StringTraits>
class CStringT :
    public CSimpleStringT<BaseType,
        _CSTRING_IMPL_::_MFCDLLTraitsCheck<BaseType, StringTraits>::c_bIsMFCDLLTraits>

【问题讨论】:

  • 它没有。您向我们展示的代码将永远无法工作。带有一个参数的模板永远不能传递两个参数。这不是模板的工作方式。
  • 我怀疑CSimpleStringT 有一个未记录的附加模板参数,该参数仅用于使用 SFINAE 技术解决模板重载问题。这通常看起来像template &lt;typename BaseType, typename Enable = void&gt; ...。在任何情况下,显示此额外参数和保留标识符(如 _CSTRING_IMPL__MFCDLLTraitsCheck)强烈表明该文档正在泄露其实现细节。我的建议是完全不用担心第二个模板参数。
  • 什么是模板重载的好资源?
  • 这是一个相当广泛的主题,但我为另一个问题写了一个有点冗长的解释:stackoverflow.com/a/55129549/5023438
  • 谢谢,我会复习的!

标签: c++ templates mfc atl


【解决方案1】:

C++ 中的类(和函数)模板的特殊之处在于它们的整个定义需要在实例化时就知道。这使得隐藏任何实现细节几乎是不可能的。 CSimpleStringT 的文档试图通过省略严格来说是实现细节的模板非类型参数来弥补这一点。

真正的类模板声明(在atlsimpstr.h中)是:

template< typename BaseType , bool t_bMFCDLL = false>
class CSimpleStringT

确实有两个模板参数(第二个有默认值),客户端代码需要提供不超过两个参数来实例化这个类模板。

不过,严格来说,CSimpleStringT 的整个存在只是一个实现细节。它出现了,因为它公开了一些由 CStringT 继承的公共 API(正如您所发现的,它使用两个模板参数实例化其基类模板)。

CStringT,仍然是一个实现细节。客户端代码从不直接使用它,而是使用两个具体的类模板实例之一:CStringWCStringA,分别用于宽字符串和 ANSI 字符串。

这里重要的一点是:C++ 类和函数模板功能强大,但对文档提出了独特的挑战。许多概念(如 CRTP)根本没有反映在源代码中,因此没有可以放置文档的源位置。在大多数其他时候,您必须在完整的文档或有用的文档之间做出决定。 CSimpleStringT 选择了有用(但不完整)的文档,CStringT 决定使用完整(但不太有用)的文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 2021-04-06
    • 2016-11-30
    • 2016-02-08
    • 1970-01-01
    • 2014-06-11
    • 2011-12-27
    相关资源
    最近更新 更多