在 C++ 中使用特征

发布于 2024-08-22 12:12:58 字数 838 浏览 6 评论 0原文

这个问题与我的上一个问题相关。我正在尝试使用 traitstraits 解决问题。请考虑以下代码。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趁年轻赶紧闹 2024-08-29 12:12:58

正在使用该专业。 traits​​::const_reference const foo。如果您希望它是一个指针,请使用:

template<typename T>
struct traits<T*>
{
    typedef const T* const_reference;
};

这样,traits​​::const_reference 将是 const foo*

请注意,traits 特化中 T 的使用与 traits 模板中的 T 完全分开。您可以重命名它:

template<typename U>
struct traits<U*>
{
    typedef const U* const_reference;
};

并且您将拥有相同的专业化。如果您有函数式编程经验,这会更有意义。

首先,将模板视为引入抽象,而不是像函数抽象出值一样。这就像变成

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 视为应用 将 Traits 模板转换为 double*。抽象出double,你就得到了:

template <typename T>
struct traits<T*> {
    typedef const T* const_reference;
};

这里的T是专门化的参数,而不是基本模板。

The specialization is being used. traits<foo*>::const_reference is const foo. If you want it to be a pointer, use:

template<typename T>
struct traits<T*>
{
    typedef const T* const_reference;
};

With this, traits<foo*>::const_reference will be const foo*.

Note that the use of T in the traits<T*> specialization is completely separate from the T in the traits template. You could rename it:

template<typename U>
struct traits<U*>
{
    typedef const U* const_reference;
};

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 turning

sum = 0
for item in [1,2,3]:
    sum += item

into:

function sum(l):
    sum = 0
    for item in l:
        sum += item
    return sum

where l takes the place of [1,2,3]. We can call sums from another function that itself has a formal parameter named l:

function sumsq(l):
    return sum(map(lambda x: x*x, l))

sumsq's "l" has nothing to do with sum's "l".

With templates, we abstract type names rather than values. That is, we turn:

struct traits {
    typedef const double& const_reference;
};

into:

template <typename T>
struct traits {
    typedef const T& const_reference;
};

Now consider a non-template specialization:

template <>
struct traits<double*> {
    typedef const double* const_reference;
};

Here there are no template parameters for the specialization, but you can think of traits<double*> as applying a traits template to a double*. Abstract out the double and you have:

template <typename T>
struct traits<T*> {
    typedef const T* const_reference;
};

Here the T is a parameter for the specialization, not the base template.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文