明らかに、constexpr
関数内で2つの文字列リテラルを連結できますが、文字列リテラルと別の文字列リテラルを連結するとどうなるでしょうか。constexpr
以下のコードのよう関数することはどうでしょうか。
template <class T>
constexpr const char * get_arithmetic_size()
{
switch (sizeof(T))
{
case 1: return "1";
case 2: return "2";
case 4: return "4";
case 8: return "8";
case 16: return "16";
default: static_assert(dependent_false_v<T>);
}
}
template <class T>
constexpr std::enable_if_t<std::is_arithmetic_v<T>, const char *> make_type_name()
{
const char * prefix = std::is_signed_v<T> ? "int" : "uint";
return prefix; // how to concatenate prefix with get_arithmetic_size<T>() ?
}
static_assert(strings_equal(make_type_name<int>, make_type_name<int32_t>);
コードは、算術型のコンパイラに依存しない文字列識別子を作成します。
編集1:
もう少し複雑な例は次のとおりです。
template<typename Test, template<typename...> class Ref>
struct is_specialization : std::false_type {};
template<template<typename...> class Ref, typename... Args>
struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
template <class T>
constexpr std::enable_if_t<is_specialization<T, std::vector>::value || is_specialization<T, std::list>::value, const char *> make_type_name()
{
return "sequence"; // + make_type_name<typename T::value_type>;
}
static_assert(strings_equal(make_type_name<std::vector<int>>(), make_type_name<std::list<int>>()));
2
バイトを含むstd配列は受け入れられますか?それ以外の場合は、マクロとコード生成を使用してこれを行うことができます。
—
Yakk-Adam Nevraumont
@ Yakk-AdamNevraumontはい、
—
Dmitriano
std::array
(そしておそらく+可変テンプレート)より良い解決策はないようです
@ Yakk-AdamNevraumont連結std :: arrays:stackoverflow.com/questions/42749032/…、ライブ例:wandbox.org/permlink/VA85KCTqxiyS2rKE
—
Dmitriano
あなたは本質的に、
—
Peter
typeid
オペレーターと同じタイプの結果を達成する何かを手回ししようとしているようです。理由のtypeid
一部は、ライブラリ関数ではなく言語の一部(たとえば、専用の言語キーワードでサポートされている)であり、その実装は「コンパイラーマジック」に依存しているため、実装からの専用のサポートなしに言語で実装することはできません。 。