C++中的typedef和using

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中的typedef和using相关的知识,希望对你有一定的参考价值。

参考技术A typedef:类型定义,将一个类型声明为另一个类型。

using:别名声明,为一个类型定义别名。

当使用STL容器时,你可能会一遍遍地写 std::unqiue_ptr,是不是觉得写起来很长,看起来也很长?而且如果哪天要改这个结构是不是要把所有出现的都替换一遍?

将函数指针分配给 constexpr 结构中的 typedef 函数的正确 C++ 方法是啥?

【中文标题】将函数指针分配给 constexpr 结构中的 typedef 函数的正确 C++ 方法是啥?【英文标题】:What is the correct C++ way to assign a function pointer to a function of typedef in a constexpr struct?将函数指针分配给 constexpr 结构中的 typedef 函数的正确 C++ 方法是什么? 【发布时间】:2021-07-03 09:36:33 【问题描述】:

如果问题措辞不完全准确,请原谅我,但我正在尝试做的(我在使用 MSVC /std:c++latest 编译时所做的)是创建一个配置项的 constexpr 结构基本的外壳类。其中一些项目是依赖于应用程序/平台的 io 函数,可读写。以下代码适用于我在添加到现有项目之前修改的 VS 解决方案。

...来自仅标题类

typedef size_t (*read_func_t)(void* const buf, size_t nbytes);
typedef size_t (*write_func_t)(const void* buf, size_t nbytes);

typedef struct shell_cfg_t 
  size_t buffer_size;
  read_func_t read;
  write_func_t write;
  size_t max_args;
 shell_cfg_t;

template<shell_cfg_t cfg>
class Shell

  public:

    Shell(const cmd_t * const cmd_table)
    : m_buf
    , m_args
    , m_readcfg.read
    , m_writecfg.write
    
      ms_cmd_table = cmd_table;
    
;

...来自 main.cpp

static size_t read_impl(void* const buf, size_t nbytes)

  // some code
  return bytes_read;


static size_t write_impl(const void* buf, size_t nbytes)

  // some code
  return bytes_written;


constexpr shell_cfg_t cfg =

  .buffer_size = 64,
  .read = read_impl,
  .write = write_impl,
  .max_args = 8
;

int main()

  Shell<cfg> sh(shell_cmd_table);

  std::string user_input_str;
  std::getline(std::cin, user_input_str);
  user_input_str += sh.kEoL;

  byte_recvd_handler((uint8_t*)(user_input_str.data()), user_input_str.length());

  sh.process();

  return 0;

这里的问题代码似乎是将 read_impl 和 write_impl 分配给结构的 .read 和 .write 。来自 GNU 10.2.0 的错误如下(底部为完整错误):

"error: 'read_impl' is not a valid template argument of type 'size_t (*)(void*, size_t)' aka 'long long unsigned int (*)(void*, long long unsigned int)' because 'read_impl' is not a variable, .read = read_impl,"

我正在处理的 GCC 和 MSVC 之间的 C++20 实现是否存在差异,或者此代码是否符合标准? constexpr 结构和命名初始化列表是我认为的新事物,但我认为以这种方式分配函数指针与新的 std 标准没有任何关系。另一种方法是对不是 nullptr 的读/写函数进行运行时检查,这是将配置结构与模板一起使用的重点。有没有更好的方法可以与 C++17 兼容?

编辑: ...与此文件相关的完整错误。整个项目输出将是 1000+ 行

../Examples/Example_Shell.cpp: In function 'int main()':
../Examples/Example_Shell.cpp:47:11: error: 'read_impl' is not a valid template argument of type 'size_t (*)(void*, size_t)' aka 'long long unsigned int (*)(void*, long long unsigned int)' because 'read_impl' is not a variable
   47 |   .read = read_impl,
      |           ^~~~~~~~~
../Examples/Example_Shell.cpp:71:28: error: invalid conversion from 'const cmd_t*' aka 'const Kernel::Shell::cmd_t*' to 'int' [-fpermissive]
   71 |   Kernel::Shell::Term<cfg> sh(shell_cmd_table);
      |                            ^~~~~~~~~~~~~~~
      |                            |
      |                            const cmd_t* aka const Kernel::Shell::cmd_t*
../Examples/Example_Shell.cpp:75:24: error: request for member 'kEoL' in 'sh', which is of non-class type 'int'
   75 |   user_input_str += sh.kEoL; // for example only. getline does not capture end line
      |                        ^~~~
../Examples/Example_Shell.cpp:79:6: error: request for member 'process' in 'sh', which is of non-class type 'int'
   79 |   sh.process();
      |      ^~~~~~~

【问题讨论】:

您显示的错误是您构建时获得的唯一输出吗?如果没有,请将 fullcomplete 构建输出复制粘贴到问题中。请在出现错误的行添加评论。 我不明白。如果要将值复制到Shell 的字段中,为什么需要模板参数? 这是一个gcc bug。 【参考方案1】:

而不是定义这个constexpr 定义一个类,然后模板将使用该类作为类型参数:

struct shell_default_cfg_t

    size_t buffer_size;
    read_func_t read;
    /* static */ size_t read(void* const buf, size_t nbytes) const 
       return read_impl(buf, nbytes);
    

    /* static */ size_t write_impl(const void* buf, size_t nbytes) 
       return write_impl(buf, nbytes);
    
;

template<typename Cfg>
class Shell

  public:

    Shell(const cmd_t * const cmd_table, Cfg cfg)
    : m_buf
    , m_args
    , m_cfgstd::move(cfg)
    
      ms_cmd_table = cmd_table;
    

    size_t read(void* const buf, size_t nbytes) const 
       return cfg.read(buf, nbytes);
    

    Cfg m_cfg;
;

【讨论】:

以上是关于C++中的typedef和using的主要内容,如果未能解决你的问题,请参考以下文章

Typedef 到 C++ 中的周围类型

如何解决 C++ 中的 typedef 重定义?

C++ 中的内部 typedef - 好风格还是坏风格?

将函数指针分配给 constexpr 结构中的 typedef 函数的正确 C++ 方法是啥?

const 成员函数和 typedef,C++

为啥 C 和 C++ 关键字“#defined”或“typedefed”也是它们的大写版本?