char 포인터에서 문자열 리터럴을 허용하고 명확하게 할 수있는 클래스를 만들려고합니다. 이 문제를 검색 할 때 제공된 솔루션은 char 포인터 만 허용하는 '홀더'클래스를 만드는 것입니다.
template< typename char_t >
class String
{
struct holder_t
{
const char_t* s;
holder_t( const char_t* s ) : s(s) {}
holder_t( char_t* s ) : s(s) {}
};
public:
// Construct from string literal
template< size_t S >
String( const char_t (&str)[S] )
{
std::cout << "String Literal: " << str;
}
// Construct from char pointer
String( holder_t h )
{
std::cout << "Char Pointer: " << h.s;
}
};
큰 아이디어는이 클래스의 인스턴스를 명시 적으로 만들 필요가 없으며 암시 적 변환에 의해 발생해야한다는 것입니다.
void StringFoo( String<char> s )
{
}
그러나 이로 인해 char 포인터에 대한 컴파일 오류가 발생하는데 왜 암시 적 변환이 작동하지 않습니까?
int main()
{
// Works!
StringFoo( "literal" );
// error C2664: 'StringFoo' : cannot convert parameter 1 from 'const char *' to 'String<char_t>'
// with [ char_t=char ]
// No constructor could take the source type, or constructor overload resolution was ambiguous
StringFoo( (const char*)"const char ptr" );
// Works!
StringFoo( String<char>((const char*)"const char ptr") );
// error C2664: 'StringFoo' : cannot convert parameter 1 from 'char *' to 'String<char_t>'
// with [ char_t=char ]
// No constructor could take the source type, or constructor overload resolution was ambiguous
StringFoo( (char*)"char ptr" );
// Works!
StringFoo( String<char>((char*)"const char ptr") );
return 0;
}
이것은 단순한 무의미한 예일뿐입니다. 내 실제 코드에서 문자열의 해시를 저장할 클래스를 만들었습니다.
문자열 리터럴이 전달되면 컴파일 타임에 해시가 생성되고 char 포인터가 전달되면 런타임에 계산됩니다.
그러나 이것은 문자열을 전달하는 사용자에게 완전히 투명해야하며 해싱은 자동으로 수행됩니다.
코드가 포인터와 함께 작동하지 않는 이유는 두 가지 버전 ( char const*
to holder
및 holder
to) 이 필요 하기 때문 String
입니다. 그러나 암시 적 변환은 최대 한 번의 변환을 수행합니다.
목적을 위해 당신은 당신이 합리적으로 단지를 구별 할 수 있다고 생각이라고 묘사 char const(&)[N]
하고 char const*
항상 어쨌든 해시를 계산하고 싶은 단지가되어 있는지 확인 이후 : constexpr
가능한 경우, 복용 버전 만드는 char const(&)[N]
트릭을해야 참조.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다