2016-08-12 2 views
2

나는 약간의 연구를하고 있는데, 어떤 단계에서는 그 클래스의 constness에 따라 어떤 데이터에서 다른 클래스를 수행하고있다.const 타입을위한 C++ 템플릿 일반화

내가 선이

const char t[] = "ABC"; 

내가 할 수 <-- HERE를 표시 수정하면 다음

작은 예를 들어 지금이 (http://coliru.stacked-crooked.com/a/75c29cddbe6d8ef6)

#include <iostream> 

template <class T> 
class funny 
{ 
public: 
    funny(T& a) : v(a) {v -= 1; } 
    virtual ~funny() { v += 1; } 
    operator T() {return v;} 

private: 
    T& v; 
}; 

#define V(a) funny<decltype(a)>(a) 

int main() 
{ 
    char t[] = "ABC"; // <-- HERE 

    if(V(t[0]) == (char)'A') 
    { 
     std::cout << "Pass" << t[0]; 
    } 
    else 
    { 
     std::cout << "No Pass" << t[0]; 
    } 
} 

처럼, 질문에 온다 컴파일 오류 :

main.cpp: In instantiation of 'funny<T>::funny(T&) [with T = const char&]': 
main.cpp:21:7: required from here 
main.cpp:7:28: error: assignment of read-only location '((funny<const char&>*)this)->funny<const char&>::v' 
    funny(T& a) : v(a) {v -= 1; } 
         ~~^~~~ 
main.cpp: In instantiation of 'funny<T>::~funny() [with T = const char&]': 
main.cpp:21:7: required from here 
main.cpp:8:27: error: assignment of read-only location '((funny<const char&>*)this)->funny<const char&>::v' 
    virtual ~funny() { v += 1; } 
        ~~^~~~ 

상수를 수정하려고하기 때문에 완전히 이해할 수 있습니다. 컴파일러가 바로 여기 있습니다. 그러나, 나는 정말이 const를 데이터도 작동해야하는, 그래서 템플릿의 const를 전문화 만들려고 :

template <class T> 
class funny <T const> 
{ 
public: 
    funny(const T& a) : v(a) {} 
    operator T() {return v;} 

private: 
    const T& v; 
}; 

그러나 상관없이, 컴파일러, 그것을 발견하지 않습니다 여전히 비를 컴파일하려고 const 버전.

어떻게해야합니까?

template <class T> 
class funny <T const> 

에 :

template <class T> 
class funny <const T&> 
+2

당신은 T'이 참조가 const를 문자 및','으로 추론 오류 메시지'에서 볼 수 있듯이 따라서'const' ('T'는'X''가''const char'' 인''X'') 형식을 따르지 않습니다. 이것은't [0]'이 표현이고 표현 인 좌변 자이기 때문입니다. 그러한 표현식의'decltype (e)'는 lvalue-reference 타입을 산출합니다. – dyp

답변

1

은 변경하면 컴파일합니다. 두 가지 옵션이 있습니다.

1) 전문화를 template <class T> class funny <T const&>으로 변경하십시오. 이 경우에는 작동하지만 const int FOO = 42; V(FOO);에는 작동하지 않습니다.

2) 변경하여 항상 비 참조 형으로 추론 매크로 V :

#define V(a) funny<typename std::remove_reference<decltype(a)>::type>(a) 
+0

실제로 그것은 :) 감사합니다! – fritzone

+1

'decltype (t [0])'이 참조이기 때문에 이것은 작동합니다. 이것은 단지 일부 const char에서는 작동하지 않습니다. @ 마일스 답변이 더 강력합니다. – TartanLlama

+0

@ TartanLlama 동의합니다. – marcinj

4

decltype(t[0]) 추론하여 const char 전문성과 일치하지 않는 const char&

관련 문제