문자열 리터럴이 아닌 다른 것에 안정적으로 static_assert하려면 어떻게해야합니까?type_traits를 사용하여 문자열 리터럴을 검색하는 방법은 무엇입니까?
예를 들어 다음 코드에서 나는 표준 어설 션 매크로를 래핑하려고 시도했지만 문자열 리터럴이 아닌 메시지에 대해서는 아무것도 거부합니다 (런타임시 문자열 리터럴이 표시되지 않기 때문에 어설트 트리거).
#include <cassert>
#include <string>
#include <type_traits>
#define my_assert(test, message)\
static_assert(\
(\
!std::is_pointer<decltype(message)>::value &&\
!std::is_array<decltype(message)>::value\
),\
"literal string required"\
);\
assert((message, (test)));
int main() {
my_assert(1 == 1, "one equals one");
my_assert(1 == 2, "one equals two");
{
const char *msg = "one equals one";
//my_assert(1 == 1, msg); // triggers static_assert
}
{
const char msg[] = "one equals one";
//my_assert(1 == 1, msg); // triggers static_assert
}
{
const std::string msg = "one equals one";
//my_assert(1 == 1, msg.c_str()); // triggers static_assert
}
{
const int msg = 3;
my_assert(1 == 1, msg); // should trigger static_assert
}
}
당신이 볼 수 있듯이
는 시험이 코드는 의도 한대로 (GCC 4.7.2 테스트) 작동, 대부분 을 type_traits 헤더가 제공하는 테스트를 통해 수행하고있다. 그러나 프로그래머가 사용할 수있는 일반적인 것들을 거부하는 것만 큼 문자열 리터럴을 특별히 찾지 않습니다.위의 예제에서는 해결책이 충분하지만 다른 상황에서도 이와 비슷한 기술을 사용하고 싶습니다.
그렇다면 어떻게 안정적으로 type_traits (또는 다른 표준 메커니즘)를 static_assert에 사용합니까? 문자열 리터럴을 제외하고 무엇입니까? 여기
실제로 어설 션이 실패 할 때 메시지를 표시 하시겠습니까? 그렇다면 다른 질문을 게시하십시오. 표준'assert()'매크로는 제 의견으로는 쓸모가 없지만 실제로 변수를 작성하여 변수의 값과 함께 메시지를 표시하는 방법은 정말 멋집니다. – Ali
@Ali 감사합니다.하지만 제 질문은 질문에 대한 대답이 유용 할 수있는 한 가지 이유를 설명하는 동기 부여 수단이었을뿐 아니라 'assert()'와는 거의 관련이 없습니다. assert가 gcc/libc가 제공하는 표준을 사용하지 못하면 큰 메시지를 받는다. 물론 정교화 된 방법을 사용하여 단언 할 수는 있지만 사실은 제 질문의 핵심은 아닙니다. 제가 말했듯이 저는 문자열 리터럴과 다른 것을 감지하는 방법에 관심이 있습니다. (내 자신의 대답은 트릭을 꽤 가깝게하는 것 같습니다.) – wjl
좋아, 나는 당신이 멋진 주장이 필요했지만. 글쎄, 행운을 비네! – Ali