ara*_*net 5 c++ runtime-error metaprogramming constants c++17
我有一个程序,它取决于 的结果std::is_same_v <const value_t, decltype(value)>
。但是,我发现当函数传递给这个表达式时,结果是意外的,导致我出现错误。
我认为返回的函数const value_t
将被视为与 相同const value_t
,但情况似乎并非如此,因为std::is_same_v <value_t, decltype(func())>
返回的是 true。
我尝试使用std::as_const、使用static_cast返回此值,从constexpr函数返回它,但它们都没有按预期工作。
一个最小的、可重现的例子:
#include <type_traits>
#include <iostream>
inline const int x = 1;
/// A constant integer variable.
inline const int y() {return x;}
/// A constant integer function returning <x>.
int main()
{
/// <x> successfully passes as being a constant.
std::cout << std::is_same_v <const int, decltype(x)> << " ";
/// But returning it from a function (<y>) does not.
std::cout << std::is_same_v <const int, decltype(y())> << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样呢?我怎样才能确保std::is_same_v <const value_t, decltype(value)>
两者std::is_same_v <const value_t, decltype(func())>
都返回 true?
y()
是纯右值表达式。该表达式的类型不是const int
, but int
。
这是因为纯右值非类非数组表达式的类型已去除其 cv 限定符。
换句话说,如果您使用类类型,它会起作用,但不适用于非类类型。
这就是语言的工作原理。const int
a和纯右值之间没有区别int
,其他基本类型也类似。它们只是限定符没有用的值。
相反,表达式x
是左值,而不是纯右值,因此 cv 限定符不会被删除。const
通过- 限定左值和非- 限定左值引用对象之间存在差异const
。
但即使如此,decltype
直接应用于非括号名称实际上也不会考虑表达式的类型,而是考虑命名实体的声明类型。这是一个特殊情况。decltype((x))
会考虑表达式类型和yield const int&
,添加左值引用,因为x
是左值。
std::invoke_result
还指定返回decltype
INVOKE 表达式的 ,所以它也会有同样的问题。
const
您可以从函数类型的返回类型中获取-qualified 类型。一种典型的方法是基于函数类型的部分专业化。不幸的是,正确地执行此操作非常麻烦,因为必须编写大量专业化内容才能涵盖所有情况。y
如果重载或通用 lambda/函子,它也将不起作用。
我的猜测是,egboost::callable_traits::return_type
是以这种方式实现的,并且会产生const
-qualified int
。
它产生预期的结果(参见https://godbolt.org/z/7fYn4q9vs):
#include <type_traits>
#include <iostream>
#include <boost/callable_traits/return_type.hpp>
inline const int x = 1;
/// A constant integer variable.
inline const int y() {return x;}
/// A constant integer function returning <x>.
int main()
{
/// <x> successfully passes as being a constant.
std::cout << std::is_same_v <const int, decltype(x)> << " ";
/// And returning it from a function (<y>) now does as well.
std::cout << std::is_same_v <const int, boost::callable_traits::return_type_t<decltype(y)>> << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
744 次 |
最近记录: |