【发布时间】:2020-03-09 11:34:46
【问题描述】:
我正在尝试使用如下所示的简单示例中的静态多态性。
#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;
}
问题是polymorphicCall 中的T 被推导出为Derived,这样任何东西都可以传递给该函数,甚至int。有没有办法只接受Base<Derived> 类型?
我尝试在模板参数上使用转发引用和enable_if,但无法推断出Bases 模板参数。
有没有办法同时使用转发引用和静态多态性?
编辑:更新了代码示例以包含实际的转发参考以及如何尝试使用它。
显示的错误是:“错误:无效使用不完整类型'struct Traits'”
【问题讨论】:
-
我仍然觉得这很混乱。在
polymorphicCall中,您已经将T推导出为Derived&。然后你引入一个类型别名Derived,它会得到类型Derived? -
还要注意
Object中的T不是转发引用,而是右值引用。 -
@super 我知道我有
T被推断为Derived,但这就是问题所在。这样,任何东西都可以被函数推断和接受。我只想接受Base<Derived>类型 -
如果这就是你想要实现的全部,你只需要改进你的类型特征并添加一个
static_assert -
@super 我试过
static_assert,但由于某种原因Trait不会;即使它在polymorphicCall中被推断为Derived,也无法识别Derived,可以查看作为Base<Derived>,它没有选择正确的专业
标签: c++ perfect-forwarding static-polymorphism