CRTP:如何推断要用作返回类型的成员类型? [英] CRTP: How to infer type of member to be used as return type?

查看:93
本文介绍了CRTP:如何推断要用作返回类型的成员类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使CRTP基本方法的返回类型取决于派生成员的类型,例如:

I would like to make the return type of a CRTP base method depend on the type of a member in the derived, as for example in:

template <typename C>
struct sum_a_b {
    ??? sum() { return static_cast<C*>(this)->a + static_cast<C*>(this)->b; }
}

template <typename T> struct a_b : sum_a_b<a_b<T>> { T a,b; };

我应该怎么代替

What should I put in place of ???

我尝试了不同的方法来声明返回类型:

I tried different ways to declare the return type :

template <typename T>
struct base {
    int get_ok() {  
        return static_cast<T*>(this)->value; 
    }
    auto get_invalid() -> decltype(static_cast<T*>(this)->value) {
        return static_cast<T*>(this)->value; 
    }
    typename T::value_type get_incomplete_type_foo() {  
        return static_cast<T*>(this)->value; 
    }
    auto get_incomplete_type_again() -> decltype(T().value) {  
        return static_cast<T*>(this)->value; 
    }
};

struct foo : base<foo> {
        typedef int value_type;
        value_type value;
};

唯一可编译的方法是 int get_ok ,对于其他人我都可以(对于 get_invalid_cast ):

The only methods that compiles is int get_ok, for the others I get either (for get_invalid_cast):

invalid static_cast from type 'base<foo>*' to type 'foo*'
     auto get_invalid() -> decltype(static_cast<T*>(this)->value) {  return static_cast<T*>(this)->value; }
                                    ^

或(其他两个)

invalid use of incomplete type 'struct foo'
     typename T::value_type get_incomplete_type_foo() {  return static_cast<T*>(this)->value; }
                            ^


推荐答案

我认为唯一的解决方法在c ++ 14之前可用的是使用类型特征:

I think the only workaround available prior to c++14 is to use a type trait:

#include <iostream>

template<typename T>
struct Value;

template <typename T>
struct Base
{
    typename Value<T>::type get_value(void)
    {  
        return static_cast<T*>(this)->m_value; 
    }
};

struct Derived;

template<> 
struct Value<Derived>
{
    using type = float;
};

struct Derived: public Base<Derived>
{
    Value<Derived>::type m_value{};
};

int main()
{
    Derived derived{};
    std::cout << derived.get_value() << std::endl;
}

在线编译器

如果 Derived 类型是模板,则键入特质特化应如下所示:

If Derived type is a template then type trait specialization would look like this:

template<typename U>
struct Derived;

template<typename U> 
struct Value<Derived<U>>
{
    using type = float;
};

这篇关于CRTP:如何推断要用作返回类型的成员类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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