분명히 constexpr
함수 에서 두 개의 문자열 리터럴을 연결할 수 있지만 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
바이트를 포함하는 표준 배열이 허용됩니까? 그렇지 않으면 매크로와 코드 생성을 사용하여이를 수행 할 수 있습니다.
—
Yakk-Adam Nevraumont
@ Yakk-AdamNevraumont 네, 더 나은 솔루션이없는 것 같습니다
—
Dmitriano
std::array
(아마도 + 가변 템플릿)
@ Yakk-AdamNevraumont 연결 std :: arrays : stackoverflow.com/questions/42749032/… , 라이브 예 : wandbox.org/permlink/VA85KCTqxiyS2rKE
—
Dmitriano
본질적으로
—
피터
typeid
연산자 와 동일한 유형의 결과를 달성하는 무언가를 수동으로 굴 리려고하는 것 같습니다 . 이유 typeid
중 일부는 라이브러리 함수가 아닌 언어의 일부입니다 (예 : 전용 언어 키워드로 지원됨). .
@Dmitriano 예, 당신은 내가 그 질문을 전에 본 적이 있음을 알 것입니다 ;)
—
Yakk-Adam Nevraumont