2011-10-13 91 views
4

以下代碼編譯並在G ++ 4.4.0和MS VC2008 Express上工作。模板中的「const const T」

#include <iostream> 

template<typename T> struct A{ 
protected: 
    T v; 
public: 
    const T get() const{ 
     return v; 
    } 

    A(T v_) 
    :v(v_){ 
    } 
}; 

class B: public A<const int*>{ 
public: 
    void doSomething() const{ 
     const int* tmp = get(); 
     std::cout << *tmp << std::endl; 
    } 

    B(const int* p) 
    :A<const int*>(p){ 
    } 
}; 

int main(int argc, char** argv){ 
    int a = 134; 
    B b(&a); 
    const B& c = b; 
    b.doSomething(); 
    c.doSomething(); 
    return 0; 
} 

然而,當我使用A<const int*>理解應導致const const int* A::get() const;。我很確定我沒有在真實的代碼中看到過類似的東西。以這種方式使用模板「合法」?

如果不是,什麼是替代品?在我的代碼中,我需要一個提供兩個「getter」方法(const/non-const)的模板類,並且可以將「const int *」作爲類型。像這樣的東西:

template<typename T> struct A{ 
protected: 
    T v; 
public: 
    const T get() const{ 
     return v; 
    } 

    T get(){ 
     return v; 
    } 

    A(T v_) 
    :v(v_){ 
    } 
}; 

任何想法?

+0

這聽起來像你有一個「不斷渴望」;) – bobobobo

回答

5

如果T = const int *,則const Tconst int * const

+0

好吧,如果我錯過了*那*的東西,那麼我想我需要休息一下。感謝您的快速回復。 – SigTerm

+5

@SigTerm:...這就是爲什麼我喜歡把'const'放在右邊......將'const'添加到'int const *'是'int const * const',這很簡單:) –

3

我們可以翻譯

const int * 

int const * 

指向一個恆定的INT。 當你有T = INT *,你有一個常量噸什麼是:

int * const 

這意味着,恆定指向一個int類型。

所以你的情況與T = const int的*,這是INT常量*,你有什麼用常量T是:

int const * const 

這意味着一個常量指針到常量INT。這是合法的。

如果不是所期望的行爲,你可能有局部的專業化,如:

template<typename T> struct A<const T>{ 
//here comes different implementation for the case where A template is 
//initialized with a const type. 
2

It's fine做到這一點

struct Foo {}; 
typedef const Foo CFoo; 

const CFoo c; 
+1

它編譯並不意味着它是合法的。 – Mat

4

它是不是有多個const預選賽的一個問題:他們只是摺疊在一起。

然而,你錯誤地解釋它,因爲你沒有正確放置它(並且它的語法允許它是一種恥辱)。

如果您將const放在之後,那麼它就符合您的要求,您會意識到您錯誤地閱讀了它。

A const T其中Tconst int*不是const const int* = const int*

如果你正確地寫:T const其中Tint const*,那麼你會讀到它int const* const,這是一個const指針const INT,而不是一個指針const INT。

0

const int const *是合法代碼,意思是指向一個常量值的常量指針。您的代碼可能轉換爲相同的表達式。

+0

不,這是錯誤的。你有什麼是const const的非const指針(如果你的表達式是合法的)。 – Mat

1

所有其他的答案站在約常量性,如果你想不合格類型,你可以使用一個小模板顱骨duggery ..

template <typename T> 
struct remove_const 
{ 
    typedef T type; 
}; 

template <typename T> 
struct remove_const<T*> 
{ 
    typedef T* type; 
}; 

template <typename T> 
struct remove_const<const T> 
{ 
    typedef T type; 
}; 

template <typename T> 
struct remove_const<const T*> 
{ 
    typedef T* type; 
}; 

template <typename T> 
void foo (T& b) 
{ 
    typename remove_const<T>::type a = b; 
} 

如果您在const指針傳遞給foo,你會請參閱a具有非常量類型,因此分配失敗。