2014-02-13 1 views
0

템플릿 메타 프로그래밍을 사용하는 문자열 조작 라이브러리에서 작업하고 있습니다. 나는 문자는 메타 프로그래밍 라이브러리를 처리 할 수있는 형태 보유 typelist 생성, 컴파일시에 원시 문자열 요소에 액세스하기 위해 C++ (11) 일반화 된 상수 식 like in this article를 사용 : 나는 매크로를 작성했습니다익명 메타 함수 (Lambda)를 구현하는 쉬운 방법

template<typename INDEX> 
struct transform_function 
{ 
    using result = tml::character<"hello world!"[INDEX::value]>; 
}; 

//tml::for_each returns the set of applications of each element of the specified 
//interval on the specified metafunction. In other words, generates a typelist 
//which contains each character of the string: 

using str = tml::for_each<tml::make_size_t_forward_iterator<0> , 
          tml::make_size_t_forward_iterator<sizeof("hello world!")> , 
          transform_function>; 

using hello2 = tml::concat<str,str>; //hello2 holds "hello world!hello world!" 

을하는 지정된 원시 문자열에서 위의 코드를 생성하고 지정된 이름으로 이름을 지정합니다. 예를 들어 :

TURBO_STRING_VARIABLE(hello , "hello "); 
TURBO_STRING_VARIABLE(world , "world!"); 

using hello_world = tml::concat<hello,world>; 

지금 내가 원하는 것은 이런 매크로, 즉, annonimous 문자열을 생성하는 것입니다 이런 식으로 뭔가 :

template<typename STRING> 
struct to_upper{ ... }; 

using HELLO_WORLD = typename to_upper<hello_world>::result; //OK, holds "HELLO WORLD!" 
using HELLO = typename to_upper<ANONYMOUS_STRING("hello")>; //HELLO 

나는를 정의 할 수 없기 때문에 내 for_each 접근 방식이 작동하지 않습니다 템플릿 argumment 패스의 컨텍스트에서 입력하지만 나는 일종의 lambda metafunction에서 argumment로 변환 함수를 직접 작성하려고 생각하고있었습니다.
Boost.MPL에는 placeholder를 사용하는 이와 비슷한 것이 있지만이 템플릿에서는 사용할 수없는 문맥에서 매개 변수를 사용하기 때문에이 컨텍스트에서는 사용할 수 없다고 생각합니다. 배열) 및 자리 표시 자 트릭을 적용 할 수 없습니다.

다른 방법이 있습니까?

+0

이것은 기사에 설명되어 있습니다. 그들은 f <_S ("Hello World!")>를 쓸 수 있습니다. –

+0

@JanHerrmann yeap하지만 문자열을 저장하기 위해 고정 길이 타입리스트를 사용하기 때문에이를 수행 할 수 있습니다. 나는 문자열의 길이와 함께 타입리스트를 원한다. 그러나 이것은 문자열의 길이를 (sizeof'와 함께) 계산해야하고, 인덱스를 문자로 변환하는 것을 통과해야합니다. 내가 필요한 것은 변환 매개 변수를 템플릿 매개 변수 내부, 즉 람다 메타 함수 안에 쓰는 것입니다. – Manu343726

답변

1

이 기사에서는 최대 길이의 문자열을 사용하여 ANONYMOUS_STRING을 구현하는 방법을 설명합니다. 이것은 일반적으로 아무 문제가 없어야합니다. 100을 최대치로 취하고 문자열이 더 길 때만 어설 션하십시오. 사용자는 짧은 문자열을 연결하여 더 긴 문자열을 만들 수 있습니다. 100 개의 문자를 사용하면 보통 긴 줄이 생기며 어쨌든 깨뜨릴 필요가 있습니다 (터미널 창에서 소스 코드의 가독성에 대해 생각하십시오).

concat< 
    ANONYMOUS_STRING("Hello "), 
    ANONYMOUS_STRING("World "), 
    ANONYMOUS_STRING("!") 
> 

이 코드를 사용하면 더 긴 문자열을 읽을 수있는 방식으로 생성 할 수 있습니다.

일반적인 문제는 문자열 리터럴 템플릿 인수 할 수 없으며 시점에서 당신이 생각할 안에 당신이 클래스를 생성 할 수있다 :

template<class T> 
struct f{}; 

using g=f<struct { /* some types and data */ }>; // does not work 

방법이 시점에서 다른 템플릿을 실체화하는 것입니다

using g=f<std::integral_constant<char, 'x'>>; // does work 

그래서 작은 문자열에는 큰 매크로를, 큰 문자열에는 작은 매크로를 만들어야한다고 생각합니다. 이것은 Abel Sinkovics와 Dave Abrahams가 기술 한 방식입니다. 좋은 효과는 TURBO_STRING_VARIABLE(hello , "hello ");을 훨씬 더 나은 것으로 바꿀 수 있다는 것입니다. using hello = ANONYMOUS_STRING("hello");

관련 문제