带有“使用"的模板模板成员继承 [英] template template member inheritance with 'using'

查看:33
本文介绍了带有“使用"的模板模板成员继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下类实现了 CRTP.我想让 Derived 类使用 Base 提供的构造函数,所以我写了 using.但是,我收到错误消息,只能从直接基类继承构造函数".等价于成员变量 x.

The following classes implement CRTP. I would like for class Derived to use the constructor provided by Base, so I write using. However, I get the error message, "can only inherit constructor from direct base". Equivalently for the member variable x.


template<template<typename, size_t> typename G, typename F, size_t U>
struct Base
{
    double x;
    Base(double x) : x{ x } {}
    double gimme_x()
    {
        return (*static_cast<G<F, U>*>(this)).gimme_x();
    }
};

template<typename F, size_t U>
struct Derived : Base<Derived, double, U>
{
    using Base<Derived, double, U>::Base;
    using Base<Derived, double, U>::x;

    double gimme_x()
    {
        return x + 1.8;
    }
};

可以通过将 Base 的模板-模板实现更改为仅使用常规模板来缓解此问题.

This problem can be mitigated by changing the template-template implementation of Base to just use a regular template.


template<typename G, typename F, size_t U>
struct Base
{
    double x;
    Base(double x) : x{ x } {}
    double gimme_x()
    {
        return (*static_cast<G*>(this)).gimme_x();
    }
};

template<typename F, size_t U>
struct Derived : Base<Derived<F, U>, double, U>
{
    using Base<Derived<F, U>, double, U>::Base;
    using Base<Derived<F, U>, double, U>::x;

    double gimme_x()
    {
        return x + 1.8;
    }
};

虽然第二个看起来有点冗长,但在这种情况下,它似乎应该与第一个等效.有什么区别,为什么第一个的实现会失败?

While the second one looks a bit more verbose, it seems like it should be equivalent to the first one in this case. What's the difference and why does the implementation of the first one fail?

推荐答案

更简单的解决方法,以避免 injected-class-name 就是使用全名::Derived.

Simpler work-around to avoid injected-class-name is to use full name ::Derived.

template<typename F, size_t U>
struct Derived : Base<Derived, double, U>
{
    using Base<::Derived, double, U>::Base;
    using Base<::Derived, double, U>::x;

    double gimme_x()
    {
        return x + 1.8;
    }
};

演示

代码与 gcc/clang 演示一起正确编译.

Code compiles correctly with both gcc/clang Demo.

这是一个msvc错误,因为

It is a msvc bug, as

在以下情况下,注入的类名被视为类模板本身的模板名:

In the following cases, the injected-class-name is treated as a template-name of the class template itself:

  • 后面跟着<
  • 用作模板参数,对应模板模板参数
  • 它是友元类模板声明的详细类说明符中的最终标识符.

这篇关于带有“使用"的模板模板成员继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆