C ++中嵌套模板函数的const限定符

时间:2019-06-13 23:35:36

标签: c++ templates const

我希望模板函数 bar const 限定符调用模板函数 foo

我有两个用于函数 foo bar 的模板及其实例化。这是 foo.cpp

#include "foo.h"
#include <iostream>

template <class T>
void foo(const T x){
    std::cout<<x[0]<<std::endl;
};
// instantiation here, in order to avoid implementation in header
template void foo<const int*>(const int*);

foo.h

template <class T>
void foo(T x);

bar.cpp

#include "bar.h"
#include "foo.h"
#include <iostream>

template <class T>
void bar(T x){
    foo<const T>(x);
};
// instantiation here, in order to avoid implementation in header
template void bar<int*>(int*);

bar.h

template <class T>
void bar(T x);

最后是 main.cpp

#include <iostream>
#include "bar.h"
#include "foo.h"
int main()
{
    int p[5];
    p[0]=17;
    foo(p);
    bar(p);
    return 0;
}

所有.h文件都包含#ifndef /#define标准语句。函数 foo 应该获取一个 int 数组,而不要对其进行更改,因此它具有 const 限定符。我希望函数 bar 接收一个 int 数组并对其进行更改,而在某个时候它还应该调用函数 foo 。使用模板的原因是,将来我想针对不同类型的数据调用这些函数,例如 double * std :: vector ,等

当我尝试编译时,出现以下错误:

undefined reference to `void foo<int* const>(int* const)'

好像无法将 int * 强制转换为 const int * 。另外,似乎将const int的指针替换为const int的指针。知道我该如何处理吗?

另一个观察结果:如果我删除 foo.cpp bar.cpp 并将所有内容合并到一个文件中,它将正常编译。

==================================

案件已解决

foo 的实例化已针对 执行。人们注意到,当在 bar 中调用 foo 时, const T 被强制转换为 T const == int * const const int * 不同。

为了将其转换为 int const * ,我添加了代码:

typedef typename std::remove_pointer<T>::type tmp_type; // tmp_type = int
foo<tmp_type const *>(x);

您需要-std = c ++ 11进行编译。或者,按照戴维斯·赫林(Davis Herring)的建议,您可以使用

foo<const std::remove_pointer_t<T>*>(x);

相反,但是您需要为此使用-std = c ++ 14。

该问题与头文件中模板的实现无关,除了显而易见的观察,如果所有内容都在一个文件中,则不需要。

另一种解决方案是对foo进行两个实例化:

template void foo<int const *>(int const *);
template void foo<int *>(int *);

第一个不允许您更改函数内部的指针的值,而第二个允许您仅在其中传递简单的 int *

1 个答案:

答案 0 :(得分:4)

如果Tint*,则const Tint *const,而不是const int*。 (毕竟,

typedef const T cT;
cT t1=/*…*/,t2=/*…*/;

这是t1=t2,而不是*t1=*t2。)

您可以使用const std::remove_pointer_t<T>*const int*构造int*