初始化一个常量变量,如果失败则断言(c++)
Initialize a constant variable and assert if failed (c++)
我想用map中的值初始化const变量,并且想断言map中是否不包含这样的值
有什么优雅的方法来实现这一点吗?
我希望c++ ternary operator ?:
能帮助我解决这个问题,但这段代码不起作用,因为ternary operator
希望在两边具有相同的类型。
const auto it = modeMap.find(key);
const Mode myMode = (it != modeMap.end()) ? myMode = it->second : assert(false && "Mode doesn't exist");
错误C2440: '初始化':不能从'void'转换为'const '模式"
如果您愿意用assert
来引发异常(无论如何可能是一个好主意),您可以通过调用std::map::at
来简化代码:
const Mode myMode = modeMap.at(key);
如果key
不在映射中,将触发std::out_of_range
。如果您确实需要assert
,那么您可以将逻辑包装在函数中:
const Mode& find_or_assert(const std::map<Key, Mode>& modeMap, const Key& key)
{
auto it = modeMap.find(key);
assert(it != modeMap.end());
return it->second;
}
然后const Mode myMode = find_or_assert(modeMap, key);
如果到达assert
部分,则myMode
无法初始化,因为assert
没有返回任何内容(void
)。您可以通过使用逗号操作符来解决这个问题:
const Mode myMode =
(it != modeMap.end()) ? myMode = it->second : (assert(false && "Mode doesn't exist"), SOME_VALUE);
在assert
执行时用SOME_VALUE
初始化myMode
。
无论如何,您使用assert
似乎无效。查看如何正确使用
最优雅的解决方案是@juanchopanza,但是如果您想要assert
而不抛出异常:
依我之见,最好为这项工作定义如下的职能:
const auto it = modeMap.find(key);
Mode& assert_value_exists(std::map<Key_Type, Mode> const& map_, Key_Type const& key) {
auto it = map_.find(key);
assert(it != map_.end());
return it->second;
}
我认为这相当于我的目标。当map中存在键时初始化const变量,否则上升断言。
const auto it = modeMap.find(key);
assert(it != modeMap.end() && "Mode doesn't exist");
const Mode myMode = it->second;
我同意这里所有的答案,断言本身不是一个好的解决方案。在生产环境中,当禁用assert且值不在映射中时,这是很危险的。正如@Jens提到的,最好抛出一个异常,或者终止你的程序。(所以推荐其他答案)。
从防御性编程的角度来看,请不要认为这个答案是最好的方法。这是对使用map中的值初始化const变量,如果map中不包含这样的键,则使用assert的问题的回答。
EDITED:正如@cad指出的链接
Assert宏被设计用来捕获编程错误,而不是用户或运行时错误,因为它通常在程序退出调试阶段后被禁用。
编辑:还想引用@Joachim Pileborg
"使用assert不适合运行时检查。首先,它会中止程序,它会看起来像崩溃,这对他人使用的任何一种程序。其次,它是一个只用于调试的宏,如果创建一个发布版本,assert宏将被替换为空空间。只要你记得这是一个宏观将在发布版本中被空白替换(这可能会导致语法错误(取决于使用它的位置)。"
- 如果没有malloc,链表实现将失败
- 如果我重新定义 sqrt 函数,为什么使用 std::sqrt 失败?
- join() 失败,如果在线程内部调用 io_context.run()
- 如果原型是本地的,则使用流 I/O C++类型约束将失败
- 如果所有部分都失败,Catch2 将再次运行测试
- 使用用户定义的类型 UDT 实例化 std::atomic<>。如果 UDT 具有虚函数,则 l 墨水将失败。为什么?
- 如果出现警告,如何立即使自动测试失败
- 避免"如果清理失败"重复的模式
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- SFINAE - 如果更复杂的功能失败,则回退到默认功能
- 如果一个人失败,如何防止多个CIN语句失败
- 如果容器不是调用函数中的引用,则使用 std::thread 传递对迭代器的引用将失败
- 如果应用程序从安装选项启动,则加载库失败,错误代码为 126
- C/C++ 套接字:如果我在 IPv6 TCP 连接之前执行任何操作,则连接将失败
- 如果 QApplication 执行延迟,QWebEngineView 在加载内容时会以静默方式失败
- 如果类没有默认可见性,静态断言如何失败
- 如果将键定义为std :: string,则存储在REDIS中的POD结构的验证将失败
- AC_CHECK_HEADER失败如果标题安装路径中有API
- Visual Studio 2010 CxxTest:如果测试失败,则生成失败
- 谷歌测试:如果测试失败,则执行其他操作