【发布时间】:2016-08-25 22:37:31
【问题描述】:
编译器:TDM-GCC-5.1.0(SJLJ 展开)
我在玩declval,我注意到我无法在它应该工作的上下文中使用它:作为typeid() 的参数。
在下面的代码中,我将declval 用于它的主要用例之一:在不通过实例的情况下获取方法的返回类型。我得到的错误是 declval 的 static_assert 消息,但这应该是不可能的,因为在这种情况下 typeid() 不会评估它的参数:
#include <typeinfo>
#include <utility>
struct Foo
{
int func();
};
int main()
{
typeid(std::declval<Foo>().func());
}
这不会为我编译(使用-std=c++14 编译时)。我唯一的猜测是我发现了一个编译器错误,或者我做了一些明显错误的事情并且我看不到它。如果是后者,我很抱歉。
编辑:
感谢ildjarn的帮助,解决方法是使用decltype,所以最后一行代码变成:
typeid(decltype(std::declval<Foo>().func()));
这很好用。然而,现在我的问题变成了:怎么会? typeid() 和 decltype() 都是未评估的上下文,所以我不确定有什么区别。
【问题讨论】:
-
试试
typeid(decltype(std::declval<Foo>().func())); -
啊,这行得通!想知道为什么会这样……
-
来自cppreference:“如果
expression不是多态类型的左值表达式,typeid不会计算表达式[.]”。我在考虑编译器错误。 -
@Quentin : Yup – "如果表达式不是多态类型的左值表达式,
typeid不会计算表达式,它标识的std::type_info对象表示表达式。" 与decltype完全一样,修复了它。 -
@Quentin :这正是我要说的完全 - 使用
decltype,它有效,应该在语义上与“版本2”相同,但它没有。 “是”的意思是“是的,绝对是编译器错误。”