【问题标题】:error in unreachable if block [duplicate]如果阻止则无法访问错误[重复]
【发布时间】:2016-05-15 22:32:08
【问题描述】:

我正在尝试执行以下操作:

template <class T>
void foo(T * ptr){
    ...a lot of code ...
    if(std::is_base_of<Bar<T>,T>::value){
        Bar<T> & bar = *ptr;
        ...a lot of code ...
    }
    ...a lot of code    
}

如果我使用 Bar 的子类来编译这个函数,一切正常,但是如果我尝试使用 which isnt 进行编译,我会在

Bar<T> & bar = *ptr;

线。 这是怎么回事,因为当 T 不是 Bar&lt;T&gt; 的子类时,不应执行此行? 如果这不是常见的方法,我该如何以正确的方式实现呢?

【问题讨论】:

  • “未执行”与“未编译”不同。
  • 它是一个模板,编译器必须为它生成代码,即使有一个条件会停止模板初始化。
  • 啊,我明白了。但我怎样才能以正确的方式做到这一点?
  • 一种方法是使用enable_if

标签: c++ templates c++11


【解决方案1】:

因为Bar&lt;T&gt;不是T的子类,

Bar<T> & bar = *ptr;

这会导致编译错误。这被包裹在一个计算结果为falseif() 语句中,并且这部分代码永远不会被执行,这一事实并没有改变这一事实。

这里正确的做法是专门化模板。

类似的东西:

template <class T, bool is_subclass=std::is_base_of<Bar<T>,T>::value>
void foo(T * ptr);

template <class T>
void foo<T, true>(T * ptr){
    ...a lot of code ...

    Bar<T> & bar = *ptr;
    ...a lot of code ...

    ...a lot of code    
}

template <class T>
void foo<T, false>(T * ptr){
    ...a lot of code ...

    ...a lot of code    
}

您现在有两种不同版本的 foo 模板,一种用于模板参数是子类的情况,另一种则不是。

foo() 的两个版本很可能会有大量的公共代码。因此,您可能需要在这里做更多的工作,将通用代码分解为它们自己的独立模板函数,您将从 foo()s 中调用它们。

【讨论】:

    【解决方案2】:

    这可以通过多种方式实现,一个例子是标签调度:

    template <class T>
    void bar(T* ptr, std::true_type)
    {
        // ...a lot of code ...
    }
    
    template <class T>
    void bar(T*, std::false_type)
    {
        // do nothing
    }
    
    template <class T>
    void foo(T * ptr){
        //...a lot of code ...
        bar(ptr, std::is_base_of<Bar<T>,T>{});
        //...a lot of code    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      • 1970-01-01
      • 2021-06-06
      • 2020-09-02
      • 2013-03-20
      • 2016-07-09
      • 2014-03-08
      相关资源
      最近更新 更多