Chromium Chronicle #24: StrongAlias, IdType ve TokenType

24. Bölüm: Łukasz Anforowicz, Bellevue, Washington tarafından (Ağustos 2021)
Önceki bölümler

Hatayı aşağıdaki kodda tespit edebiliyor musunuz? Görür müydünüz? hata kod incelemesi yaparken ne anlama geliyor?

Token CreateToken(int command_data, int buffer_id);
...
auto token = CreateToken(GetCommandBufferId(), GetCommandData());

Aynı tür, bazen uyumsuz alanlardan gelen değerleri temsil edebilir. Bu durum genellikle tam sayılar veya dizeler gibi belirli olmayan veri türlerinde yaşanır. Yukarıdaki örnekte, bunun nasıl hatalara neden olabileceği gösterilmektedir. Neyse ki Chromium'un //base özelliği uygunsuz, farklı türlerin tanıtılmasını kolaylaştırır:

#include "base/types/strong_alias.h"

// The first template argument of StrongAlias is a "tag" type.
// The "tag" type is used to distinguish between different
// StrongAlias types.
using CommandData = base::StrongAlias<class CommandDataTag, int>;
using CommandBufferId = base::StrongAlias<class CommandBufferIdTag, int>;

Token CreateToken(CommandData command_data, CommandBufferId buffer_id);

Ayrı türler okunabilirliği iyileştirir. Buna ek olarak StrongAlias, derleme sırasında tür karışıklarını yakalar:

test.cc:456:16: error: no matching function for call to 'CreateToken'
  auto token = CreateToken(GetCommandBufferId(), GetCommandData());
               ^~~~~~~~~~~
test.cc:123:7: note: candidate function not viable: no known conversion from
'StrongAlias<class CommandBufferIdTag, [...]>' to
'StrongAlias<class CommandDataTag, [...]>' for 1st argument
Token CreateToken(CommandData command_data, CommandBufferId buffer_id);
      ^

Derleyici, türlerin uyumsuz olduğunu görür. çünkü farklı bir "etikete" sahipler türü. StrongAlias tüm türleri "etiket" olarak kabul eder türü. Örnekte, "etiket" herhangi bir yerde tür tanımına bile gerek yoktur. mevcut olmayan bir sınıfın yerleşik yönlendirme bildirimi düzgün şekilde çalışır.

İleride, belirli olmayan bir tür (örneğin bool, int, string) yerine şu alternatifleri göz önünde bulundurun:

  • Tanımlayıcı olarak int32_t yerine base::IdType32<TagType> kullanın.
  • Spesifik olmayan bir base::UnguessableToken yerine base::TokenType<TagType> kullanın.
  • Bool yerine enum sınıfı kullanın (örneğin, true yerine kForReload, kNotForReload, false).
  • Spesifik olmayan diğer türleri base::StrongAlias<TagType, SomeWrappedType> ile değiştirin.