C++ 如何使用需要非常量引用的函数编写decltype表达式?
考虑:C++ 如何使用需要非常量引用的函数编写decltype表达式?,c++,templates,c++11,decltype,C++,Templates,C++11,Decltype,考虑: int convert_it(std::string& x) { return 5; } void takes_int_ref(int& i) { } 我想写一个函数,它只存在于convert\u可以应用它,并且传递到的结果取int\u ref的情况下。也就是说,功能体是: template <typename A> void doit(A& a) { int i = convert_it(a); takes_int_re
int convert_it(std::string& x)
{
return 5;
}
void takes_int_ref(int& i)
{
}
我想写一个函数,它只存在于convert\u可以应用它
,并且传递到的结果取int\u ref
的情况下。也就是说,功能体是:
template <typename A>
void doit(A& a)
{
int i = convert_it(a);
takes_int_ref(i);
}
但是,它看起来很粗糙,decltype
不再反映函数体的功能。本质上,问题似乎在于decltype
只接受一个表达式,而函数体中需要两条语句
在这里,正确的方法是什么?使用:
模板
自动完成(A&A)->取消类型(
取整数参考(标准::十二<
decltype(转换它(std::declval())
&>()),void())
{ .. }
std::declval()
提供类型为A&
的表达式<代码>转换它(A&)将有效或无效-如果无效,则失败。如果它是有效的,就说它有类型T
。然后,您尝试使用T&
调用takes\u int\u ref
,以查看这是否有效。如果是,您将进入void
。如果不是,则替换失败。记录在案,在看到std::declval
解决方案后,我对黑客行为的看法发生了变化,我最终采用了以下方法:
template <typename T> T& lref_of(T&&);
template <typename A>
auto doit(A& a) -> decltype(takes_int_ref(lref_of(convert_it(a))), void())
{ .. }
模板T&lref_of(T&&);
模板
auto doit(A&A)->decltype(获取int\u ref(lref\u of(convert\u it(A))),void())
{ .. }
因为我是从一个表达式而不是一个类型开始的,所以做
lref\u of(convert\u it(a))
比std::declval()
更简洁。另外,如果在任何代码中使用了lref\u,则不定义lref\u将导致编译时错误,这比定义它在运行时简单地抛出异常要好。是std::result\u of
和std::enable\u if
的帮助吗?听起来正是我需要的!问题,为什么需要declval表达式中的&
s?@Claudiu,因为您需要一个左值引用declval()
给了你一个T&
,但是declval()
给了你一个T&
。有趣的是,这让我觉得我的版本没有那么粗俗,如果我把gimme\u-ref
重命名为ref-of
并且根本不定义主体,这看起来更干净:decltype(takes\int\u-ref(ref)of(convert\it(a)),void()
@Claudiu是的。我想也没有必要使用std::declval()
,因为a
已经是a&
。我想我把它放在那里是为了免费的。是的,让我们继续吧。
template <typename T>
T& gimme_ref(T t) { throw std::runtime_error("No"); return t; }
template <typename A>
auto doit(A& a) -> decltype(takes_int_ref(gimme_ref(convert_it(a))), void())
template <typename A>
auto doit(A& a) -> decltype(
takes_int_ref(std::declval<
decltype(convert_it(std::declval<A&>()))
&>()), void())
{ .. }
template <typename T> T& lref_of(T&&);
template <typename A>
auto doit(A& a) -> decltype(takes_int_ref(lref_of(convert_it(a))), void())
{ .. }