C++:将 const 与模板参数结合起来

问题描述 投票:0回答:6

当我手动替换

T
char *
时,以下示例可以正常工作,但为什么不能按原样工作:

template <typename T>
class A{
  public:
    A(const T _t) { }
};

int main(){
  const char * c = "asdf";
  A<char *> a(c);
}

使用 gcc 编译时,出现此错误:

test.cpp: In function 'int main()':
test.cpp:10: error: invalid conversion from 'const char*' to 'char*'
test.cpp:10: error:   initializing argument 1 of 'A<T>::A(T) [with T = char*]'
c++ templates constants const-correctness c++-templates
6个回答
10
投票

T
替换
char*
会给出指向 char 的
const
指针,而
c
被声明为指向
const char
的指针。

解决方案是通过值获取指针和整型,通过 const 引用获取类类型。如果可以的话,请使用 Boost Call Traits 来为您解决此类问题。


2
投票

我猜这是因为你的函数需要

const (char *)
(因为T是
char *
),即你无法更改它指向的地址,而
const char *
代表
(const char) *
,即你无法更改该值就在指针指向的地方。


2
投票

这里发生的事情是,编译器知道您的模板是用

T = char*
实例化的,并且首先尝试查看您提供的值 (
c
) 是否是
char*
(它不是;它是
const char*
) 检查其常量之前。

因此您需要:

  1. const_cast
    价值
    c
  2. 指定
    A<const char *> a(c);
  3. 从 A 构造函数的声明中删除
    const
    说明符

其中最好做的是#3。这会让你失去我认为你需要的“保证”:用于初始化 A 类对象的值是常量。为了再次实现这一目标,您必须使用一些类型特征模板约束的实现来确保当T不是

const
类型时模板无法被实例化。


1
投票

如果在c赋值之前删除const,程序将编译。

发生的情况是构造函数不一定采用实例的 const 版本。 const 告诉构造函数您不能更改 T _t 中的数据,它实际上不是构造函数范围内的 const 对象......这是一个非常微妙但重要的区别。


1
投票

如果你创建你的构造函数

A(const char* _t)
,你就会变得高效
A( (const char) *t)
。即指向 const char 的指针。但是当您指定
char*
作为模板参数时,您将有效地获得
A( const (char *t))
,或者指向 char 的 const 指针。

换句话说,我认为您遇到了文章仲夏夜的疯狂中讨论的相同问题,除了使用模板参数而不是 typedef。


0
投票

尝试转换为 const T&。另外,在这些情况下,您应该让编译器自动推导模板参数,而不是指定它。

© www.soinside.com 2019 - 2024. All rights reserved.