Tuesday Coding Tip 06 - Explicit template instantiation

2 5 28
calendar_todayschedule2 min read
— Originally published at medium.com

Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.


Templated code in C++ must be defined in the header files (or a function within the same .cpp file). This is because whenever a templated function is called, the compiler generates a new implementation using the concrete type the function was called with. If you split the definition from the declaration, you need to tell it what implementations to generate and link.

That’s what explicit template instantiation is for. It is useful when you’re writing generic code for a well-known subset of types, like string manipulation. It cannot be used for totally generic types because you need to be able to list all types the template will be used with (otherwise the user will get a linker error).

// .hpp
#pragma once

#include <string>
#include <concepts>

// Note me using constructible_from instead of is_same_v. This will
// get me into trouble
template<class T>
concept NarrowOrWideString = std::constructible_from<std::string, T>
|| std::constructible_from<std::wstring, T>;

template<NarrowOrWideString StringType>
StringType StrTransformation(StringType source);

template<NarrowOrWideString StringType>
class ClassTemplate
{
public:
    static StringType StrTransformation(StringType source);
};
// .cpp
template<NarrowOrWideString StringType>
StringType StrTransformation<StringType>(StringType source)
{
   /* some transformation */
   return source;
}

template std::string StrTransformation<std::string>(std::string);
template std::wstring StrTransformation<std::wstring>(std::wstring);


template<NarrowOrWideString StringType>
StringType ClassTemplate<StringType>::StrTransformation(StringType source)
{
   /* some transformation */
   return source;
}

template class ClassTemplate<std::string>;
template class ClassTemplate<std::wstring>;
// main.cpp
int main()
{
   {
      // This links, note the explicitly created string in parameters
      auto str = StrTransformation(std::string("aaa"));
    
      auto wstr = StrTransformation(std::wstring(L"bbb"));
    
      // ERROR: Type does not conform to concept
      // auto num = StrTransformation(10);
    
      // ERROR: Type does conform to concept,
      // but template was not instantiated for const char[4]
      // auto str2 = StrTransformation("aaa");
    
      // This works, template overload was explicitly specified
      // and the concept allows conversion of const char* to std::string
      // Note that if I used is_same_v instead of constructible_from,
      // I couldn't use const char* as an argument.
      auto str3 = StrTransformation<std::string>("aaa");
    
      // Or I can make an alias
      constexpr auto&& StrTransformationA = StrTransformation<std::string>;
      auto str4 = StrTransformationA("aaa");
   }
  
   {
      // ERROR: C++ template type deduction is not good enough
      // auto str1 = ClassTemplate::StrTransformation(std::string("aaa"));
    
      // I need to be explicit
      auto str2 = ClassTemplate<std::string>::StrTransformation("aaa");
    
      // Or make an alias
      using ClassTemplateA = ClassTemplate<std::string>;
      auto str3 = ClassTemplateA::StrTransformation("aaa");
   }
}

1 Comment

2 votes
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Tuesday Coding Tip 02 - Template with type-specific API

Jakub Neruda - Mar 10

Tuesday Coding Tip 08 — Explicit template specialization

Jakub Neruda - Apr 21

Tuesday Coding Tip 05 - Object initialization in C++

Jakub Neruda - Mar 31

Tuesday Coding Tip 15 — Mathematical constants in C++

Jakub Neruda - Jun 9

Tuesday Coding Tip 13 — Deleting problematic overloads

Jakub Neruda - May 26
chevron_left
847 Points35 Badges
Brno, Czech Republiclinkedin.com/in/jakub-neruda
19Posts
10Comments
9Connections
Experienced C++ developer, team lead and hobby gamedev. I enjoy writing stuff about C++, clean code, clean architecture, and game development.

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!