在 C++ 中使用特征
这个问题与我的上一个问题相关。我正在尝试使用 traits
和 traits
解决问题。请考虑以下代码。
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*
。我在这里做错了什么?
任何帮助都会很棒!
This question is related to my last one. I am trying to solve the problem using traits<T>
and traits<T*>
. Please consider the following code.
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;
}
So it looks like compiler is not considering the traits specialization for pointers and taking return type of value()
as const foo
rather than const foo*
. What am I doing wrong here?
Any help would be great!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正在使用该专业。
traits::const_reference
是const foo
。如果您希望它是一个指针,请使用:这样,
traits::const_reference
将是const foo*
。请注意,
traits
特化中T
的使用与traits
模板中的 T 完全分开。您可以重命名它:并且您将拥有相同的专业化。如果您有函数式编程经验,这会更有意义。
首先,将模板视为引入抽象,而不是像函数抽象出值一样。这就像变成
:
其中
l
代替了[1,2,3]
。我们可以从另一个函数调用sums
,该函数本身有一个名为l
的形式参数:sumsq
的“l”与无关>sum
的“l”。使用模板,我们抽象类型名称而不是值。也就是说,我们将: 变为
:
现在考虑非模板特化:
这里没有用于特化的模板参数,但您可以将
traits
视为应用将 Traits
模板转换为double*
。抽象出double
,你就得到了:这里的
T
是专门化的参数,而不是基本模板。The specialization is being used.
traits<foo*>::const_reference
isconst foo
. If you want it to be a pointer, use:With this,
traits<foo*>::const_reference
will beconst foo*
.Note that the use of
T
in thetraits<T*>
specialization is completely separate from the T in thetraits
template. You could rename it:and you'll have the same specialization. It makes more sense if you've experience in functional programming.
To start, think of the
template <typename ...>
as introducing an abstraction, rather like a function abstracts out a value. It's like turninginto:
where
l
takes the place of[1,2,3]
. We can callsums
from another function that itself has a formal parameter namedl
:sumsq
's "l" has nothing to do withsum
's "l".With templates, we abstract type names rather than values. That is, we turn:
into:
Now consider a non-template specialization:
Here there are no template parameters for the specialization, but you can think of
traits<double*>
as applying atraits
template to adouble*
. Abstract out thedouble
and you have:Here the
T
is a parameter for the specialization, not the base template.