这个问题和我上一个one有关.我正在尝试使用 traits<T>
解决问题和 traits<T*>
.请考虑以下代码。
template<typename T>
struct traits
{
typedef const T& const_reference;
};
template<typename T>
struct traits<T*>
{
typedef const T const_reference;
};
template<typename T>
class test
{
public:
typedef typename traits<T>::const_reference const_reference;
test() {}
const_reference value() const {
return f;
}
private:
T f;
};
int main()
{
const test<foo*> t;
const foo* f = t.value(); // error here. cannot convert ‘const foo’ to ‘const foo*’ in initialization
return 0;
}
所以看起来编译器没有考虑指针的特征特化并采用 value()
的返回类型作为const foo
而不是 const foo*
.我在这里做错了什么?
任何帮助都会很棒!
最佳答案
正在使用特化。 traits<foo*>::const_reference
是 const foo
.如果你想让它成为一个指针,使用:
template<typename T>
struct traits<T*>
{
typedef const T* const_reference;
};
有了这个,traits<foo*>::const_reference
将是 const foo*
.
注意使用T
在traits<T*>
特化与 traits
中的 T 完全分开模板。您可以重命名它:
template<typename U>
struct traits<U*>
{
typedef const U* const_reference;
};
并且您将拥有相同的专长。如果您有函数式编程经验,它会更有意义。
首先,想想 template <typename ...>
就像引入抽象一样,就像函数抽象出一个值一样。就像转身一样
sum = 0
for item in [1,2,3]:
sum += item
进入:
function sum(l):
sum = 0
for item in l:
sum += item
return sum
哪里l
代替[1,2,3]
.我们可以调用sums
来自另一个函数,它本身有一个名为 l
的形式参数:
function sumsq(l):
return sum(map(lambda x: x*x, l))
sumsq
的“l”与sum
无关的“l”。
使用模板,我们抽象类型名称而不是值。也就是说,我们转:
struct traits {
typedef const double& const_reference;
};
进入:
template <typename T>
struct traits {
typedef const T& const_reference;
};
现在考虑一个非模板特化:
template <>
struct traits<double*> {
typedef const double* const_reference;
};
这里没有特化的模板参数,但是可以想到traits<double*>
作为应用 traits
模板到 double*
.摘出double
你有:
template <typename T>
struct traits<T*> {
typedef const T* const_reference;
};
这里是 T
是专门化的参数,而不是基本模板。
关于c++ - 在 C++ 中使用特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2304792/