【问题标题】:Static Cast to CRTP Interface [duplicate]静态转换为 CRTP 接口 [重复]
【发布时间】:2021-07-22 19:44:16
【问题描述】:

我正在构建一个 CRTP 接口并注意到一些未定义的行为。因此,我构建了一些示例代码来缩小问题范围。

#include <iostream>

template <typename T>
class Base {
public:
    int a() const { return static_cast<T const&>(*this).a_IMPL(); }
    int b() const { return static_cast<T const&>(*this).b_IMPL(); }
    int c() const { return static_cast<T const&>(*this).c_IMPL(); }
};

class A : public Base<A> {
public:
    A(int a, int b, int c) : _a(a), _b(b), _c(c) {}

    int a_IMPL() const { return _a; }
    int b_IMPL() const { return _b; }
    int c_IMPL() const { return _c; }
    
private:
    int _a;
    int _b;
    int _c;
};

template <typename T>
void foo(const T& v) {
    std::cout << "foo()" << std::endl;
    
    std::cout << "a() = " << static_cast<Base<T>>(v).a() << std::endl;
    std::cout << "b() = " << static_cast<Base<T>>(v).b() << std::endl;
    std::cout << "c() = " << static_cast<Base<T>>(v).c() << std::endl;
}

int main() {
    A v(10, 20, 30);
    
    std::cout << "a() = " << v.a() << std::endl;
    std::cout << "b() = " << v.b() << std::endl;
    std::cout << "c() = " << v.c() << std::endl;
    
    foo(v);
    
    return 0;
}

这段代码的输出是:

a() = 10
b() = 20
c() = 30
foo()
a() = 134217855
b() = 0
c() = -917692416

似乎在将实现 CRTP“接口”的子类转换为接口本身时出现了一些问题。这对我来说没有意义,因为 A 类显然是从 Base 继承的,所以我不应该能够将 A 的实例转换为 Base 吗?

谢谢!

【问题讨论】:

  • static_cast&lt;Base&lt;T&gt;&gt; - 您正在转换为一个值,从而导致切片。
  • @StoryTeller-UnslanderMonica 你是对的。我犯了一个愚蠢的错误......

标签: c++ templates crtp


【解决方案1】:

您在投射到 Base&lt;T&gt; 时复制和切片。

改为const Base&lt;T&gt;&amp;

std::cout << "a() = " << static_cast<const Base<T>&>(v).a() << std::endl;
std::cout << "b() = " << static_cast<const Base<T>&>(v).b() << std::endl;
std::cout << "c() = " << static_cast<const Base<T>&>(v).c() << std::endl;

【讨论】:

    【解决方案2】:

    事实证明我错误地转换为一个值而不是一个引用

    std::cout << "a() = " << static_cast<Base<T>>(v).a() << std::endl;
    

    应该变成

    std::cout << "a() = " << static_cast<const Base<T>&>(v).a() << std::endl;
    

    【讨论】:

    • ...好吧,这就是我的回答已经说过的:-)
    猜你喜欢
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    相关资源
    最近更新 更多