static_assert를 사용하여 무언가를 강제로 실패 시키려고합니다. 특정 템플릿 함수를 특정 방식으로 인스턴스화하려고하면 컴파일러 오류가 발생합니다. 나는 그것을 작동시킬 수는 있었지만, 그것은 정말로 추악했습니다. 이 작업을 수행하는 더 쉬운 방법이 있습니까?static_assert (false)를 호출하는 올바른 방법은 무엇입니까?
이것은 첫 번째 시도였습니다. 이것은 전혀 작동하지 않았습니다. 아무도이 기능을 사용하지 않더라도 항상 오류를 생성합니다.
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
다음은 두 번째 시도입니다. 실제로 작동합니다. 이 전화를하지 않으면 오류가 발생하지 않습니다. 이 코드를 호출하면이 행을 가리키는 매우 읽기 쉬운 오류 메시지가 나타나고이를 인스턴스화하려고 시도한 코드를 가리 킵니다.
template< class T >
void marshal(std::string name, T *value)
{
static_assert(std::is_pod<T>::value && !std::is_pod<T>::value, "You cannot marshal a pointer.");
}
문제는이 코드가 가장 좋지 않다는 점입니다. 해킹처럼 보입니다. 다음 번에 최적화 수준을 변경하고 내 컴파일러를 업그레이드하고 재채기 등을 할 때 컴파일러는이 두 번째 사례가 첫 번째 사례와 동일하다는 것을 인식하고 둘 다 작동하지 않을 것입니다.
내가하려는 일을하는 더 좋은 방법이 있습니까?
여기에 약간의 컨텍스트가 있습니다. 서로 다른 입력 유형에 사용할 수있는 marshal()의 여러 버전이 필요합니다. 템플릿을 기본 케이스로 사용하는 하나의 버전이 필요합니다. 나는 char *를 제외한 어떤 포인터도 특별히 허용하지 않는 또 다른 것을 원한다.
void marshal(std::string name, std::string)
{
std::cout<<name<<" is a std::string type."<<std::endl;
}
void marshal(std::string name, char *string)
{
marshal(name, std::string(string));
}
void marshal(std::string name, char const *string)
{
marshal(name, std::string(string));
}
template< class T >
void marshal(std::string name, T value)
{
typedef typename std::enable_if<std::is_pod<T>::value>::type OnlyAllowPOD;
std::cout<<name<<" is a POD type."<<std::endl;
}
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
int main (int argc, char **argv)
{
marshal(“should be pod”, argc);
marshal(“should fail to compile”, argv);
marshal(“should fail to compile”, &argc);
marshal(“should be std::string”, argv[0]);
}
에 기본 템플릿의 정의를 변경해야합니까? – cpplearner
@cpplearner 일부 사람들은 선택적 매개 변수로 enable_if를 템플릿에 숨 깁니다. 호출자가 우연히 그 (가짜) 매개 변수를 채울 수 없기 때문에 이것은 더 좋아 보인다. –