Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用需要非常量引用的函数编写decltype表达式?_C++_Templates_C++11_Decltype - Fatal编程技术网

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()) 
{ .. }