C++ `常量T`with T=char*不是`const char*`?

C++ `常量T`with T=char*不是`const char*`?,c++,templates,pointers,constants,typedef,C++,Templates,Pointers,Constants,Typedef,我有一个通用链接列表: template <class E> class linked_element { linked_element<E> *last = nullptr, *next = nullptr; const E elem; public: explicit linked_element(const E elem) : elem(elem) { } linked_element(const linked_element&

我有一个通用链接列表:

template <class E>
class linked_element {
    linked_element<E> *last = nullptr, *next = nullptr;
    const E elem;
public:
    explicit linked_element(const E elem) : elem(elem) { }
    linked_element(const linked_element& cpy) : next(cpy.next), last(cpy.last), elem(cpy.elem) { }
    ~linked_element() {
        if(next != nullptr) next->last = last;
        if(last != nullptr) last->next = next;
    }
    linked_element& operator =(linked_element& other) {
        if(this != &other) {
            last = other.last;
            next = other.next;
            elem = other.elem;
        }
        return *this;
    }

    void add(linked_element<E> *next) {
        next->last = this;
        this->next = next;
    }

    const E& get() {
        return elem;
    }

    linked_element<E> *getLast() {
        return last;
    }

private:
    linked_element() = default;
};

template <class T>
class linked_list {
    linked_element<T*> *end = nullptr;
    std::size_t size = 0;
public:
    linked_list() = default;

    void push(const T& elem) {
        auto e = new linked_element<T*>(&elem);
        if(end != nullptr) end->add(e);
        end = e;
        size++;
    }

    T& peek() {
        checkAndCrash();
        return *(end->get());
    }

    void pop() {
        checkAndCrash();
        auto tmp = end->getLast();
        delete end;
        end = tmp;
        size--;
    }

    bool empty() {
        return size == 0;
    }

    void checkAndCrash() {
        //...
    }
};
模板
类链接元素{
链接的_元素*last=nullptr,*next=nullptr;
常数;
公众:
显式链接元素(常量元素):元素(元素){
链接元素(常量链接元素&cpy):next(cpy.next)、last(cpy.last)、elem(cpy.elem){
~linked_元素(){
如果(next!=nullptr)next->last=last;
如果(last!=nullptr)last->next=next;
}
链接元素和运算符=(链接元素和其他){
如果(此!=&其他){
last=other.last;
next=other.next;
elem=其他.elem;
}
归还*这个;
}
空添加(链接的元素*下一个){
下一个->最后一个=这个;
这个->下一个=下一个;
}
const E&get(){
返回元素;
}
链接的元素*getLast(){
最后返回;
}
私人:
链接的元素()=默认值;
};
模板
类链表{
链接的_元素*end=nullptr;
std::size\u t size=0;
公众:
链表()=默认值;
无效推送(常量T&elem){
自动e=新链接的元素(&elem);
如果(结束!=nullptr)结束->添加(e);
结束=e;
大小++;
}
T&peek(){
checkAndCrash();
return*(end->get());
}
void pop(){
checkAndCrash();
自动tmp=end->getLast();
删除结束;
end=tmp;
大小--;
}
bool empty(){
返回大小==0;
}
void checkAndCrash(){
//...
}
};
但当我尝试将其与char一起使用时:

int main() {
    using std::string;

    string a("a"), b("b"), c("c");

    linked_list<char> list;

    list.push('a');
    list.push('b');
    list.push('c');

    while (!list.empty()) {
        std::cout << list.peek() << std::endl;
        list.pop();
    }
    return 0;
}
intmain(){
使用std::string;
字符串a(“a”)、b(“b”)、c(“c”);
链表;
list.push('a');
list.push('b');
list.push('c');
而(!list.empty()){

std::cout我有一个
T=int
。现在我想要一个
const T
。所以一个常量
T
,或者一个
const int

我有一个
T=char*
。现在我想有一个
const T
。一个常量
T
,一个常量
char*
一个
char*const
。这是一个重要的区别。指针本身是常量,而不是它所指向的值

如果将
const T
中的
T
替换为其值
char*
,则可以得到
const char*
,但类型系统不是这样工作的:)


类似地,对于
T=char&
const T
将是
char&
,而不是
const char&
,因为没有常量引用这样的情况,所以它被忽略。

我有一个
T=int
。现在我想有一个
const T
。所以有一个常量
T
,或
const int

我有一个
T=char*
。现在我想有一个
const T
。一个常量
T
,一个常量
char*
一个
char*const
。这是一个重要的区别。指针本身是常量,而不是它所指向的值

如果将
const T
中的
T
替换为其值
char*
,则可以得到
const char*
,但类型系统不是这样工作的:)


类似地,对于
T=char&
const T
将是
char&
,而不是
const char&
,因为没有常量引用这样的情况,所以它被忽略。

要回答主题行中的问题-不,结果是
char*const
,而不是
const char
。因此指针是常量d不是指向的值。是否有任何方法以
const char*
结束?相关:存储
&elem
是一个坏主意。引用可能指的是一个临时变量,其生存期将很快到期-事实上,您调用
push('a')的方式就是这种情况
@aschepler谢谢,代码确实有很多错误,但没有意识到这一点。要回答主题行中的问题-否,结果是
char*const
,而不是
const char*
。因此指针是常量,而不是指向的值。是否有任何方法以
const char*
结束?相关:存储
&elem
不是一个好主意。引用可能指的是一个生存期即将到期的临时变量-事实上,您调用
push('a')的方式就是这样的
@aschepler谢谢,代码确实有很多错误,我没有意识到这一点。有没有办法以
const char*
结束?因为在列表元素中,
const
被忽略。@EmmanuelMess在构造函数中使用
remove\u pointer*
将需要我传递一个指向
remove\u pointer
的指针,并且它只能被忽略y删除一个“定点”层如果我有E=int**同样的问题会出现。我该如何使用它?@EmmanuelMess
remove\u pointer
做它所宣传的,它会删除一个指针层。你不必提供指向
remove\u pointer
的指针,因为你应该使用名为
type
的底层类型成员。构造函数应该以一个
const std::remove\u pointer\u t*
为例。标准中没有递归的remove指针,因此请看的答案。是否有任何方法以
const char*
结束?因为list\u元素中的一个aik,
const
被忽略。@EmmanuelMess在构造函数中使用
remove\u pointer*
将需要我传递一个p指向
移除\u指针的指针
,它只移除一个“指针”层如果我有E=int**同样的问题会出现。我该如何使用它?@EmmanuelMess
remove\u pointer
做它所宣传的,它会删除一个指针层。你不必提供指向
remove\u pointer
的指针,因为你应该使用名为
type
的底层类型成员。构造函数应该以一个
const std::remove\u pointer\u t*
为例。标准中没有递归的remove指针,因此请看一看的答案。
In file included from .../linked_list/main.cpp:3:0:
.../linked_list/linked_list.hpp: In instantiation of ‘void linked_list<T>::push(const T&) [with T = char]’:
.../linked_list/main.cpp:12:15:   required from here
.../linked_list/linked_list.hpp:53:40: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
   auto e = new linked_element<T*>(&elem);
                                        ^
[...]