-1

If CStringT inherits from CSimpleStringT and the class definition for CSimpleStringT is as follows, according to the CSimpleString Documentation:

template<typename BaseType>
class CSimpleStringT

How does CSimpleStringT have two template arguments? Are they both of the same BaseType parameter such that template<typename BaseType, class BaseType> class CSimpleStringT?

From the CStringT Documentation:

template<typename BaseType, class StringTraits>
class CStringT :
    public CSimpleStringT<BaseType,
        _CSTRING_IMPL_::_MFCDLLTraitsCheck<BaseType, StringTraits>::c_bIsMFCDLLTraits>
alter_igel
  • 6,899
  • 3
  • 21
  • 40
user2364556
  • 117
  • 1
  • 1
  • 3
  • 1
    It doesn't. The code you've shown us would never work. A template with one argument can never be passed two. That's not how templates work. – Silvio Mayolo Apr 06 '21 at 15:52
  • I suspect that `CSimpleStringT` has an undocumented additional template parameter which is only used for template overload resolution using SFINAE techniques. This would typically look like `template ...`. In any case, showing this extra parameter and reserved identifiers like `_CSTRING_IMPL_` and `_MFCDLLTraitsCheck` strongly suggests that this documentation is leaking its implementation details. My advice is to not worry about the second template parameter at all. – alter_igel Apr 06 '21 at 15:58
  • Whats a good resource for template overloading? – user2364556 Apr 06 '21 at 16:01
  • It's a pretty broad subject, but I wrote a somewhat lengthy explanation a while back for another question: https://stackoverflow.com/a/55129549/5023438 – alter_igel Apr 06 '21 at 16:12
  • Thanks I will review! – user2364556 Apr 06 '21 at 16:56
  • @alt `CSimpleStringT`'s non-type template argument controls part of its behavior. It is used in partial template specializations, pretty standard template stuff, no complex SFINAE, or flexible overload resolution. None of that is particularly interesting, since client code never uses `CSimpleStringT`. It's an abstraction layer that was introduced when merging MFC's and ATL's string types. – IInspectable Apr 06 '21 at 19:48
  • Indeed, client code never uses `CStringT` either. Client code uses either the `CStringW` or `CStringA` class template instantiation. The issue here is common with template code in C++: It's near impossible to write useful documentation. – IInspectable Apr 06 '21 at 20:20
  • @IInspectable sounds like you have an answer – alter_igel Apr 07 '21 at 04:17

1 Answers1

1

Class (and function) templates in C++ are special in that their entire definition needs to be known at the point of instantiation. That makes it near impossible to hide any implementation details. The documentation for CSimpleStringT tries to compensate for that by omitting the template non-type parameter that is strictly an implementation detail.

The true class template declaration (in atlsimpstr.h) is:

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

There are indeed two template parameters (with the second one having a default value), and client code needs to provide no more than two parameters to instantiate this class template.

Strictly speaking, though, the entire existence of CSimpleStringT is an implementation detail. It surfaces, since it exposes some of the public API, inherited by CStringT (which, as you found out, instantiates its base class template using two template arguments).

CStringT, still, is an implementation detail. Client code never uses it directly, but would rather use one of two concrete class template instantiations: CStringW or CStringA, for wide and ANSI character strings, respectively.

The important take-away here is: C++ class and function templates are powerful, yet impose unique challenges to documentation. Many concepts (like the CRTP) aren't reflected in source code at all, so there's no source location where you could place the documentation. At most other times you have to decide between documentation that's complete or documentation that's helpful. CSimpleStringT opted for helpful (yet incomplete), where CStringT decided to use complete (yet less than helpful) documentation.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • "one of two concrete class template instantiations: CStringW or CStringA" technically typedefs of specific specializations rather than full derived concrete implementation classes.... – David V. Corbin May 05 '22 at 13:49
  • @dav A `typedef` doesn't introduce a new type. It literally just allows clients to use a different name to refer to the *same* type. With `typedef Foo foo;` there is absolutely nothing in the language that would allow you to discern a difference between `Foo` and `foo`. You cannot have overloads that only differ by `Foo` or `foo`, and you cannot have template specializations for `Foo` and `foo`. I don't know why you believe that having a template specialization and a type alias for it would make for a relevant distinction. The language doesn't care, so why do you? – IInspectable May 05 '22 at 16:39
  • Yes, that is exactly my point.. the original part where I quoted are not really "concrete instantications". If it was "class CStringW : CStringT<...>" then they really would be quite concrete and distinct. – David V. Corbin May 05 '22 at 20:03
  • @dav *afxstr.h* supplies both explicit template instantiations alongside their `typedef`'d shorthands. `CStringW` is indeed an alternative name for the explicit template instantiation `template class ATL::CStringT< wchar_t, StrTraitMFC_DLL< wchar_t > >;`. I'm failing to see a substantial issue with the wording I chose. I'm also failing to see a substantial attempt at improving it. – IInspectable May 06 '22 at 10:24
  • Let me see if I can find the paper from many years ago about the differences between typedef'ing a template specialization and creating a derived class from the fully specialized template. A portion (but not all of it) revolves around control of what can done by other developers.... – David V. Corbin May 06 '22 at 14:04
  • @dav I'm not sure that's going to be useful here. No one is going to derive from a `CStringT` instantiation. – IInspectable May 06 '22 at 15:48