c++ - 具有转发引用的静态多态性

标签 c++ perfect-forwarding static-polymorphism

我正在尝试使用静态多态性,如下所示的简单示例。

#include <iostream>

template <typename Derived>
struct Base
{
    decltype(auto) foo() { return static_cast<Derived&>(*this).foo(); }
};

struct Derived : Base<Derived>
{
    void foo() { std::cout << "Derived" << std::endl; }
};

template <typename T>
struct Traits;

template <typename T>
struct Traits<Base<T>>
{
    using Derived = T;
};


template <typename T>
struct Object
{
    template <typename U>
    Object(U&& data) : m_data(std::forward<U>(data)) {}

    T m_data;
};

template <typename T>
decltype(auto) polymorphicCall(T&& obj)
{
    using Derived = typename Traits<std::decay_t<T>>::Derived; 
    return Object<Derived>(static_cast<Derived&>(obj));
}

int main()
{
    Derived d;
    polymorphicCall(d);

    return 0;
}

问题是 TpolymorphicCall推导为Derived ,这样任何东西都可以传递给该函数,甚至 int 。有没有办法只接受 Base<Derived>类型?

我尝试使用转发引用和 enable_if在模板参数上,但我无法推断出 Base s 模板参数。

有没有办法同时使用转发引用和静态多态性?

编辑:更新了代码示例以包括实际的转发引用以及如何尝试使用它。

显示的错误是:“错误:无效使用不完整类型'struct Traits'”

链接:https://godbolt.org/z/3EcS47

最佳答案

如果目标只是将 polymorphicCall 的使用限制为从 Base 派生的类型,您可以使用 static_assert 和类型来实现特质。

#include <iostream>

template <typename Derived>
struct Base
{
    decltype(auto) foo() { return static_cast<Derived&>(*this).foo(); }
};

struct Derived : Base<Derived>
{
    void foo() { std::cout << "Derived" << std::endl; }
};

template <typename T, typename = void>
struct IsDerivedFromBase : std::false_type {};

template <typename T>
struct IsDerivedFromBase<T, std::enable_if_t<std::is_base_of_v<Base<T>, T>>> : std::true_type {};


template <typename T>
struct Object
{
    template <typename U>
    Object(U&& data) : m_data(std::forward<U>(data)) {}

    T m_data;
};

template <typename T>
decltype(auto) polymorphicCall(T&& obj)
{
    using Derived = std::remove_cvref_t<T>;
    static_assert(IsDerivedFromBase<Derived>::value);
    return Object<Derived>(std::forward<T>(obj));
}

int main()
{
    Derived d;
    polymorphicCall(d);
    int i;
    //polymorphicCall(i);

    return 0;
}

关于c++ - 具有转发引用的静态多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60599750/

相关文章:

c++ - 转发复制构造函数的问题

c++ - C++ 静态多态性和方法名称

c++ - 如何正确使用 "C++ Core Guidelines: C.146: Use dynamic_cast where class hierarchy navigation is unavoidable"

C++:重构管理命名空间

c++ - 在完美转发中 `decltype(std::forward<Args>(args))...` 和 Args&& 有什么区别

C++ 元编程为树结构分配唯一 ID

c++ - 完美转发可变参数模板到标准线程

c++ - 将静态访问者与静态多态性层次结构耦合

java - 我可以将 C++ 代码与 JAVA 代码一起使用吗?

c++ - C++ 中具有 n 个控制点和 k 阶的 B 样条曲线