"const const T" в шаблоне - PullRequest
       13

"const const T" в шаблоне

4 голосов
/ 13 октября 2011

Следующий код компилируется и работает на G ++ 4.4.0 и MS VC2008 Express.

#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_){
    }
};

Есть идеи?

Ответы [ 6 ]

5 голосов
/ 13 октября 2011

Если T = const int *, то const T равно const int * const.

4 голосов
/ 13 октября 2011

Наличие нескольких квалификаторов const не является проблемой: они просто складываются вместе.

Однако вы неправильно его интерпретируете, потому что неправильно его размещаете (и жаль, что синтаксис позволяет это).

Если вы поместите const после типа, который он квалифицирует, вы поймете, что неправильно его прочитали.

A const T, где Tis const int* is NOT const const int* = const int*.

Если вы напишите правильно: T const, где T is int const*, тогда вы прочтете его int const* const, который является указателем constconst int, а НЕ указатель на const int.

3 голосов
/ 13 октября 2011

Мы можем перевести

const int *

в

int const *

Указатель на константу int.Когда у вас есть T = int *, то с помощью const T вы получаете:

int * const

Что означает постоянный указатель на int.

Так что в вашем случае с T = const int*, что составляет int const *, то, что вы имеете с const 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 голосов
/ 13 октября 2011

Это нормально сделать это

struct Foo {};
typedef const Foo CFoo;

const CFoo c;
1 голос
/ 13 октября 2011

Все остальные ответы касаются константности. Если вы хотите использовать неквалифицированный тип, вы можете использовать небольшой шаблон черепа-копания.

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 имеет неконстантный тип, и, следовательно, присваивание завершится неудачей.

0 голосов
/ 13 октября 2011

const int const * является допустимым кодом и означает постоянный указатель на постоянное значение. Ваш код, вероятно, переводится в то же выражение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...