Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.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中的引用(返回T而不是T&;其中T&;是decltype)_C++_Templates_C++11_Type Deduction - Fatal编程技术网

C++ 删除decltype中的引用(返回T而不是T&;其中T&;是decltype)

C++ 删除decltype中的引用(返回T而不是T&;其中T&;是decltype),c++,templates,c++11,type-deduction,C++,Templates,C++11,Type Deduction,(如果您是C++11专业人士,请跳到粗体部分。) 假设我想编写一个模板方法,该方法调用并返回传递对象的结果,该对象的类型是模板参数: template<ReturnType, T> ReturnType doSomething(const T & foo) { return foo.bar(); // EDIT: Might also be an expression introducing a temp val } 由于类型扣除,我们不必编写MyClass,调用变

(如果您是C++11专业人士,请跳到粗体部分。)

假设我想编写一个模板方法,该方法调用并返回传递对象的结果,该对象的类型是模板参数:

template<ReturnType, T>
ReturnType doSomething(const T & foo) {
    return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
由于类型扣除,我们不必编写
MyClass
,调用变成:

int x = doSomething<int>(object);
编译器现在将找出
foo.bar()
的类型,并将其用作返回类型。对于我们的具体类
MyClass
,这将是一个
int
,以下内容就足够了:

int x = doSomething(object);
现在回答我的问题:

如果MyClass将
bar()
定义为返回
int&
,则
doSomething(object)
的返回类型也将是
int&
=
decltype(foo.bar())
。这是一个问题,因为G++现在遵守了这一点,我将返回对temporary的引用

我怎样才能解决这个问题?是否有类似于
remove\u reference
的东西可以像
remove\u reference(decltype(foo.bar())
那样使用

我想声明一个helper方法,它接受一个
T&
并返回一个
T
,然后将
doSomething
的返回类型定义为
decltype(helper(foo.bar())
)。但我感觉到必须有更好的方法。要删除引用:

#include <type_traits>

static_assert(std::is_same<int, std::remove_reference<int&>::type>::value, "wat");
#包括
静态断言(std::is_same::value,“wat”);
就你而言:

template <typename T>
auto doSomething(const T& foo)
    -> typename std::remove_reference<decltype(foo.bar())>::type
{
    return foo.bar();
}
模板
自动剂量测量(常量T&foo)
->typename std::remove_reference::type
{
返回foo.bar();
}

需要明确的是,请注意,以书面形式返回引用是可以的:

#include <type_traits>

struct f
{
    int& bar() const
    {
        static int i = 0;
        return i;
    } 
};

template <typename T>
auto doSomething(const T& foo)
    -> decltype(foo.bar())
{ 
    return foo.bar();
}

int main()
{
    f x;
    return doSomething(x);
}
#包括
结构f
{
int&bar()常量
{
静态int i=0;
返回i;
} 
};
模板
自动剂量测量(常量T&foo)
->decltype(foo.bar())
{ 
返回foo.bar();
}
int main()
{
fx;
返回剂量测定法(x);
}
返回的引用可以简单无误地传递。你在评论中的例子是它变得重要和有用的地方:

template <typename T>
auto doSomething(const T& foo)
    -> decltype(foo.bar())
{ 
    return foo.bar() + 1; // oops
}
模板
自动剂量测量(常量T&foo)
->decltype(foo.bar())
{ 
返回foo.bar()+1;//oops
}

这是个什么问题?你要做的就是传递参考资料。是的,还有
std::remove_reference::type
@GManNickG我不想在我的程序中出现警告。我想用
-Werror-Wall
编译。谢谢你的
std::remove_reference
提示,我知道我以前见过这个,但在谷歌上搜索“c++11模板类型推断移除引用”时找不到它,也许我的搜索太本地化了:)不,我是说根本不应该有警告。如果
foo.bar()
foo.bar()
是一个坏例子,比如说
return foo.bar()+1
。在我的例子中,我正在使用迭代器,并希望推断所提供的容器类型的
T
,该容器类型具有
begin()
,因此我的decltype是
decltype(*container.begin())
,它是
T&
。因为我返回了一个临时的
T
,所以我需要删除引用。公平地说,我将把这个区别添加到我的答案中。在C++14中,您还可以在C++14中使用
std::remove_reference_t
@Kupiakos。您可以使用自动返回类型,而不使用尾随decltype。@AlyssaHaroldsen我找不到多少关于
std::remove_reference_t
的文档。这与
std::remove\u reference
有何不同?
std::remove\u reference\u t
相当于
std::remove\u reference::type
。这是一种简写方式,类似于
std::remove\u reference\u v
,其中
\u v
表示
::value
#include <type_traits>

struct f
{
    int& bar() const
    {
        static int i = 0;
        return i;
    } 
};

template <typename T>
auto doSomething(const T& foo)
    -> decltype(foo.bar())
{ 
    return foo.bar();
}

int main()
{
    f x;
    return doSomething(x);
}
template <typename T>
auto doSomething(const T& foo)
    -> decltype(foo.bar())
{ 
    return foo.bar() + 1; // oops
}