类模板参数扣除类,并带有其他非类型参数

发布于 2025-02-12 05:40:34 字数 669 浏览 0 评论 0原文

在这种情况下,是否可以使CTAD适用于t

enum class boundary_type:int{inclusive, exclusive};

template<class T, boundary_type left, boundary_type right>
struct interval
{
    using value_type = T;

    T begin;
    T end;
};

我试图添加分点指南


template<boundary_type left, boundary_type right, class T>
interval(T, T) -> interval<T, left, right>;

,但仍然有错误

模板参数数量错误(2,应为3)

尝试时

interval<boundary_type::inclusive, boundary_type::exclusive>{0, 2}

Is it possible to make CTAD work for T in this case?

enum class boundary_type:int{inclusive, exclusive};

template<class T, boundary_type left, boundary_type right>
struct interval
{
    using value_type = T;

    T begin;
    T end;
};

I tried to add the decuction guide


template<boundary_type left, boundary_type right, class T>
interval(T, T) -> interval<T, left, right>;

But still gets error

wrong number of template arguments (2, should be 3)

when trying

interval<boundary_type::inclusive, boundary_type::exclusive>{0, 2}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

只想待在家 2025-02-19 05:40:34

CTAD无法与明确指定的模板参数一起使用 。但是您可以使用普通模板功能来执行此操作

template<boundary_type left, boundary_type right, class T>
auto make_interval(T begin, T end) {
  return interval<T, left, right>{begin, end};
}

int main() {
  auto intval = make_interval<boundary_type::inclusive, 
                              boundary_type::exclusive>(0, 2);
}

CTAD cannot work with the partially explicitly specified template parameter. But you can do this using normal template function

template<boundary_type left, boundary_type right, class T>
auto make_interval(T begin, T end) {
  return interval<T, left, right>{begin, end};
}

int main() {
  auto intval = make_interval<boundary_type::inclusive, 
                              boundary_type::exclusive>(0, 2);
}
静若繁花 2025-02-19 05:40:34

有了更多的代码,您可以通过为包含有关这些包装器提供的信息的边界信息的边界提供包装器类型来使用类似的语法:使用:

enum class boundary_type :int { inclusive, exclusive };

template<class T>
struct exclusive
{
    static constexpr ::boundary_type boundary_type = ::boundary_type::exclusive;
    using value_type = T;

    explicit exclusive(T bound)
        : m_bound(bound)
    {
    }

    operator T() const
    {
        return m_bound;
    }

    T m_bound;
    
};

template<class T>
struct inclusive
{
    static constexpr boundary_type boundary_type = ::boundary_type::inclusive;
    using value_type = T;

    inclusive(T bound)
        : m_bound(bound)
    {
    }

    operator T() const
    {
        return m_bound;
    }

    T m_bound;
    
};

template<class T, boundary_type left, boundary_type right>
struct interval
{
    using value_type = T;

    T begin;
    T end;
};

template<class Left, class Right>
interval(Left, Right) -> interval<
    std::common_type_t<typename std::remove_cvref_t<Left>::value_type, typename std::remove_cvref_t<Right>::value_type>,
    std::remove_cvref_t<Left>::boundary_type,
    std::remove_cvref_t<Right>::boundary_type
>;

使用

interval intrvl{ inclusive(0), exclusive(2) };
static_assert(std::is_same_v<decltype(intrvl), interval<int, boundary_type::inclusive, boundary_type::exclusive>>);

With a bit more code you could allow the user to use a similar syntax by providing wrapper types for the boundaries containing information about the boundaries on information provided by those wrappers:

enum class boundary_type :int { inclusive, exclusive };

template<class T>
struct exclusive
{
    static constexpr ::boundary_type boundary_type = ::boundary_type::exclusive;
    using value_type = T;

    explicit exclusive(T bound)
        : m_bound(bound)
    {
    }

    operator T() const
    {
        return m_bound;
    }

    T m_bound;
    
};

template<class T>
struct inclusive
{
    static constexpr boundary_type boundary_type = ::boundary_type::inclusive;
    using value_type = T;

    inclusive(T bound)
        : m_bound(bound)
    {
    }

    operator T() const
    {
        return m_bound;
    }

    T m_bound;
    
};

template<class T, boundary_type left, boundary_type right>
struct interval
{
    using value_type = T;

    T begin;
    T end;
};

template<class Left, class Right>
interval(Left, Right) -> interval<
    std::common_type_t<typename std::remove_cvref_t<Left>::value_type, typename std::remove_cvref_t<Right>::value_type>,
    std::remove_cvref_t<Left>::boundary_type,
    std::remove_cvref_t<Right>::boundary_type
>;

usage

interval intrvl{ inclusive(0), exclusive(2) };
static_assert(std::is_same_v<decltype(intrvl), interval<int, boundary_type::inclusive, boundary_type::exclusive>>);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文