【问题标题】:how to check std::is_base_of<> on (*this)如何检查 (*this) 上的 std::is_base_of<>
【发布时间】:2020-04-03 13:08:13
【问题描述】:

对于某些任务,如果没有宏,我就无法逃脱。现在我想至少添加一些防止误用的保护。

我想static_assert MYMACRO() 被使用

  1. 在基类的子类中,...
  2. ...即在run()方法中

天真的方法失败了:

static_assert(std::is_base_of<Base, typeid(*this)>::value, "Use MYMACRO() only in subclass of Base.");
//                                  =============
//       SubOne would work, but not typeid(*this)
//
static_assert(__func__ == "run", "Use MYMACRO() only in run() method.");
//            ========
//       not a constexpr?
//

复制:

#ifndef __GNUG__
#error "Needs GCC C++"
#endif

#define MYMACRO() \
{\
    do { \
    /*> > > want static_assert'ions here < < <*/\
    /*here comes stuff I coudn't put into an [inline] function,*/ \
    /*because it contains GCC Labels-as-Values and */ \
    /*conditional return;*/ \
    } while(false);\
}

class Base {
public:
    virtual int run() = 0;
};

class SubOne : Base {
public:
    int run() override {
        // ...
        MYMACRO();
        // ...
    };
};

class SubTwo : Base {
public:
    int run() override {
        // ...
        MYMACRO();
        // ...
    };
};

int main(void) 
{
    SubOne sub1;
    SubTwo sub2;
    //a little embedded app
    while (true) {
        sub1.run();
        sub2.run();
    }
}

预测可能的问题:
它是干什么用的? - http://dunkels.com/adam/dunkels06protothreads.pdf
标签作为值:-https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
为什么不使用上下文切换“正确”RTOS? - 我希望上述解决方案能够简化本机架构下的单元测试,避开对native (POSIX) portQEMU/renodetarget board 的需求。 (不是针对所有人,而是针对许多测试)

【问题讨论】:

  • decltype获取表达式的类型,而不是typeid

标签: c++ gcc typetraits static-assert protothread


【解决方案1】:

typeid(*this) 替换为std::decay_t&lt;decltype(*this)&gt;

并且,要在编译时比较字符串,请使用std::string_view

static_assert(std::string_view(__func__) == "main", "Use MYMACRO() only in run() method.");

【讨论】:

    【解决方案2】:

    typeid 在这里是错误的工具,因为它返回一个指向 type_info 实例的引用,它不是 *this 的类型,而只包含有关类型的信息。

    你可以使用decltype:

    #include <iostream>
    #include <type_traits>
    
    
    struct base {};
    
    struct foo : base {
        foo() {
            static_assert(std::is_base_of<base,std::remove_reference<decltype(*this)>::type>::value);
        }
    };
    
    struct foo_fail {
        foo_fail() {
            static_assert(std::is_base_of<base,std::remove_reference<decltype(*this)>::type>::value);
        }
    };
    

    编译器输出:

    prog.cc: In constructor 'foo_fail::foo_fail()':
    prog.cc:15:23: error: static assertion failed
             static_assert(std::is_base_of<base,std::remove_reference<decltype(*this)>::type>::value);
                           ^~~
    

    【讨论】:

      猜你喜欢
      • 2017-12-16
      • 1970-01-01
      • 2016-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      相关资源
      最近更新 更多