我正在测试我的容器包装器是否正确实现URefs.我能想到的唯一明显的方法是试图找出一种检测物体是否被移动的方法.
有没有一种好的测试方法可以确保没有复制对象?还是有另一种方法来测试我想要的东西?我更喜欢不需要修改我正在测试的类的解决方案.因为有几十个.
你能提供一些关于你有什么的更多信息吗?就像你的容器,你如何使用它,你能否修改它等等.也许你可以在不修改容器的情况下测试它,而是使用特殊的容器元素类型 - 跟踪副本和移动.
几个不同的容器和一些独立的模板功能.大多数情况下,它是围绕STL库类型的包装器,如deque,list,map,set等.
考虑以下两点:
template <class Function>
void apply(Function&& function)
{
std::forward<Function>(function)();
}
Run Code Online (Sandbox Code Playgroud)
和
template <class Function>
void apply(Function&& function)
{
function();
}
Run Code Online (Sandbox Code Playgroud)
在什么情况下有差异,它有什么具体的区别?
Scott Meyers 说(对于功能模板的参数):
通用引用只能以"
T&&" 形式出现!即使简单地添加const限定符也足以禁用"&&"作为通用引用的解释.
为什么C++没有const通用引用?有技术原因吗?
我很好奇,一般来说,你是否要使用T &&(通用引用)而不是经典的T const&(l值引用)来模拟以C++ 11开头的模板化函数参数.我特别好奇的是,如果你想要处理r值引用,你如何绕过这个事实,你被迫失去const; 有没有解决的办法?
假设我的代码中的某个地方是一个foo带有通用引用参数的函数,我无法更改:
template<typename T>
auto foo(T&& t) { std::cout<<"general version"<<std::endl; }
Run Code Online (Sandbox Code Playgroud)
现在我想foo为给定的类重载A,并确保A调用任何限定符和引用类型的重载.为此,我可以蛮力地为所有可能的资格提供超载(暂时忽略volatile):
auto foo(A & a) { std::cout<<"A&"<<std::endl; }
auto foo(A const& a) { std::cout<<"A const&"<<std::endl; }
auto foo(A && a) { std::cout<<"A &&"<<std::endl; }
auto foo(A const&& a) { std::cout<<"A const&&"<<std::endl; }
Run Code Online (Sandbox Code Playgroud)
演示.然而,这对于更多参数来说非常严重.
或者,我可以传递值,这似乎也捕获了以前的所有情况:
auto foo(A a) { std::cout<<"A"<<std::endl; }
Run Code Online (Sandbox Code Playgroud)
演示.然而,现在需要复制大对象( - 至少原则上).
这些问题有一种优雅的方式吗?
请记住,我无法更改通用参考功能,因此SFINAE等不可能.
我想int通过r-或l-值(const)引用将参数(某些具体类型,例如)传递给成员函数.我的解决方案是:
#include <type_traits>
#include <utility>
struct F
{
using desired_parameter_type = int;
template< typename X, typename = typename std::enable_if< std::is_same< typename std::decay< X >::type, desired_parameter_type >::value >::type >
void operator () (X && x) const
{
// or even static_assert(std::is_same< typename std::decay< X >::type, desired_parameter_type >::value, "");
std::forward< X >(x); // something useful
}
};
Run Code Online (Sandbox Code Playgroud)
另一个例子是http://pastebin.com/9kgHmsVC.
但它太冗长了.如何以更简单的方式做到这一点?
也许我应该使用叠加std::remove_reference而std::remove_const不是std::decay,但这里只是简化.
下面我有一个名为ProxyCall的模板函数,它接受一个对象,一个成员函数及其参数.它只是将调用转发给成员函数.
我希望能够在不使用模板限定符的情况下调用该函数(想象大量此类调用具有多个参数).当我尝试传递const引用参数时,类型推导主要起作用,但编译器(msvc和gcc 4.9)都是barf.
#include <string>
struct Widget {
void f(const std::string& s, bool b) {}
};
template<typename T, typename... Args>
void ProxyCall(T &obj, void(T::*method)(Args...), Args&&... args) {
(obj.*method)(std::forward<Args>(args)...);
}
int main(int argc, char* argv[])
{
Widget w;
std::string s;
ProxyCall<Widget, const std::string&, bool>(w, &Widget::f, s, true); // OK
ProxyCall(w, &Widget::f, (const std::string&)s, true); // also OK
ProxyCall(w, &Widget::f, s, true); // ERROR: template parameter is ambiguous
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何修改上面的代码,以便编译器自动推导出类型,而无需借助显式模板限定符或显式转换.考虑到编译器已经从Widget :: f的签名中知道确切的参数类型,这似乎应该是可能的.
我很难理解将函数引用作为通用引用传递给函数时究竟发生了什么(正在推导出什么类型).假设我们有一个函数foo,它将param作为通用引用:
template<typename T>
void foo(T&& param)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
然后让我们做以下事情:
void(&f)(int) = someFunction;
foo(f);
Run Code Online (Sandbox Code Playgroud)
结果将是:
void foo(T&&) [with T = void (&)int]
这是完全可以理解的:我们将lvalue传递给我们的函数foo,因此推导的类型是void(&)int,并且param的类型将是"void(&&&)int",它在参考折叠规则下变为无效(& )INT.Param只是函数的左值引用.
但是当我做以下事情时:
void(&f)(int) = someFunction;
foo(std::move(f));
Run Code Online (Sandbox Code Playgroud)
foo将打印:
void foo(T&&) [with T = void (&)int]
这和以前完全一样!这里发生了什么?为什么结果与传递左值相同?我希望由于我们将rvalue传递给foo,推导出的类型应该是T = void(int),而param应该变为void(&&)int.这总是与所有其他"普通"类型(如类,基元类型等)一起发生.为什么在处理函数引用时它会有所不同?
在以下代码中,使用的好处是&&什么?该代码来自Specialize相同运算符的不同特征的答案
从这个问题,我得到一个&&参数意味着它是一个可以被函数修改的引用。
的decay_t可能阻止编译器解释为阵列的变量的引用,如在什么是标准::衰变和时,应使用什么?
std::forward是完美的描述转发在这里。为什么我们需要这种转发?
谢谢。
#include <iostream>
#include <type_traits>
#include<utility>
class A;
template <typename T>
struct is_A : std::false_type {};
template <> struct is_A<A> : std::true_type {};
template <typename T>
struct is_int : std::false_type {};
template <> struct is_int<int> : std::true_type {};
template <> struct is_int<long> : std::true_type {};
class A{
public:
int val;
void print(void){
std::cout << val << std::endl;
}
template <typename T1>
std::enable_if_t<is_int<std::decay_t<T1>>::value, …Run Code Online (Sandbox Code Playgroud) 我认为通用引用(T&&)应该采用任何类型的引用.但以下不起作用.
当我尝试在我正在编写的库中进行const-correct时,我遇到了这个问题.我是C++的新手,之前没见过这样的东西.
TEST.CPP:
enum Cv_qualifier {
constant,
non_const
};
template <Cv_qualifier Cv> class A;
template<>
class A<Cv_qualifier::constant> {
public:
template<Cv_qualifier Cv2>
void t(const A<Cv2>&& out) {}
};
template <>
class A<Cv_qualifier::non_const> {
public:
template<Cv_qualifier Cv2>
void t(const A<Cv2>&& out) {}
};
int main()
{
A<Cv_qualifier::non_const> a;
A<Cv_qualifier::constant> b;
a.t(b);
}
Run Code Online (Sandbox Code Playgroud)
错误(编译g++ test.cpp -std=c++11):
test.cpp: In function ‘int main()’:
test.cpp:24:10: error: cannot bind ‘A<(Cv_qualifier)0u>’ lvalue to ‘const A<(Cv_qualifier)0u>&&’
a.t(b);
^
test.cpp:17:10: note: initializing argument 1 of ‘void …Run Code Online (Sandbox Code Playgroud)