如果你有这个功能
template<typename T> f(T&);
Run Code Online (Sandbox Code Playgroud)
然后尝试调用它,让我们说一个rvalue就好
f(1);
Run Code Online (Sandbox Code Playgroud)
为什么T不能被推导为const int,使得参数成为一个const int&因而可以绑定到一个rvalue?
现在我用下面的一段代码dummily转换基本类型(int,long,char[],这种东西),以std::string进行进一步的处理:
template<class T>
constexpr std::string stringify(const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
Run Code Online (Sandbox Code Playgroud)
但是我不喜欢它依赖的事实std::stringstream.我尝试使用std::to_string(来自C++ 11的保留节目)然而它会扼杀char[]变量.
有一种简单的方法可以为这个问题提供优雅的解决方案吗?
在阅读维基百科关于decltype的页面时,我很好奇这个陈述,
其[decltype]的主要用途是在通用编程中,通常很难甚至不可能命名依赖于模板参数的类型.
虽然我可以理解该语句的难点部分,但是需要命名一个无法在C++ 03下命名的类型的示例是什么?
编辑:我的观点是,因为C++中的所有内容都有类型声明.为什么会出现无法命名类型的情况?此外,是不是设计用于产生类型信息的特质类?特质课可以替代decltype吗?
为什么以下代码有效:
template<typename T1>
void foo(T1 &&arg) { bar(std::forward<T1>(arg)); }
std::string str = "Hello World";
foo(str); // Valid even though str is an lvalue
foo(std::string("Hello World")); // Valid because literal is rvalue
Run Code Online (Sandbox Code Playgroud)
但不是:
void foo(std::string &&arg) { bar(std::forward<std::string>(arg)); }
std::string str = "Hello World";
foo(str); // Invalid, str is not convertible to an rvalue
foo(std::string("Hello World")); // Valid
Run Code Online (Sandbox Code Playgroud)
为什么示例2中的左值不会以与示例1中相同的方式解析?
另外,为什么标准认为需要在std :: forward与简单推导中提供参数类型很重要?无论类型如何,简单地呼唤前方都表现出意图.
如果这不是标准的东西,只是我的编译器,我使用msvc10,这将解释蹩脚的C++ 11支持.
谢谢
编辑1:将文字"Hello World"更改为std :: string("Hello World")以生成rvalue.
我有一个操作矢量的代码:
template<typename T>
void doVector(vector<T>& v, T&& value) {
//....
v.push_back(value);
//...
}
Run Code Online (Sandbox Code Playgroud)
正常情况下push_back,我需要使用forward(value),move(value)还是仅仅value(根据新的C++ 11)?它们如何影响性能?
例如,
v.push_back(forward<T>(value));
Run Code Online (Sandbox Code Playgroud) 我有以下代码将成员函数绑定到类的实例:
class Foo {
public:
int i;
void test() {
std::cout << i << std::endl;
}
};
int main() {
Foo f;
f.i = 100;
auto func = std::bind(&Foo::test, std::forward<Foo>(f));
f.i = 1000;
func();
}
Run Code Online (Sandbox Code Playgroud)
但该std::bind声明并未f通过引用绑定.调用func打印"100"而不是"1000"这是我想要的.
但是,如果我更改语句以获取指针它是否有效.
auto func = std::bind(&Foo::test, &f);
Run Code Online (Sandbox Code Playgroud)
但是,这是通过f由指针我的理解,因为我认为std::bind需要一个R值的参考Arg&&(如图所示这里)如何工作的呢?
有人可以解释一下吗?
在测试某些功能的同时std::thread,一位朋友遇到了GCC的问题,我们认为值得问一下这是否是GCC错误或者这个代码可能有问题(代码打印(例如)"7 8 9 10 1 2 3" ,但我们希望打印[1,10]中的每个整数:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <thread>
int main() {
int arr[10];
std::iota(std::begin(arr), std::end(arr), 1);
using itr_t = decltype(std::begin(arr));
// the function that will display each element
auto f = [] (itr_t first, itr_t last) {
while (first != last) std::cout<<*(first++)<<' ';};
// we have 3 threads so we need to figure out the ranges for each thread to show
int increment = std::distance(std::begin(arr), std::end(arr)) / 3;
auto first …Run Code Online (Sandbox Code Playgroud) 我有一个号码的C++函数void f(),R g(T a),S h(U a, V b)等.我想写一个接受一个模板功能f,g,h等作为模板参数,并调用该函数.
即我想要这样的东西:
template<MagicStuff, WrappedFunction>
ReturnType wrapper(MagicallyCorrectParams... params)
{
extra_processing(); // Extra stuff that the wrapper adds
return WrappedFunction(params);
}
...
wrapper<f>(); // calls f
wrapper<g>(T()); // calls g
wrapper<h>(U(), V()); // calls h
Run Code Online (Sandbox Code Playgroud)
template<typename ReturnType, typename Args...>
ReturnType wrapper(ReturnType (*wrappee)(Args...), Args... args)
{
extra_processing();
return wrappee(args...);
}
...
wrapper(f); // calls f OK
wrapper(g, T()); …Run Code Online (Sandbox Code Playgroud) 我希望创建一个函数,它接受任意数量的仿函数对象,或者更通常只是可调用对象(不同类型),并将它们应用于内部数据结构.该函数将在我的代码中的不同点使用不同数量的仿函数.
而不是使不同的版本接受1,2,3 ......等重复代码我想到使用可变参数模板.
我找到了一个解决方案,我将在下面发布作为答案,因为我在Google上找不到任何具体的内容,而其他人可能会觉得它很有用.但是,如果有人有任何更好的想法发布,请.我觉得应该有一个标准的方法来做到这一点?
我知道这不行,但我的第一次尝试是
#include <iostream>
using namespace std;
struct FunctorA {
void operator() () {
cout << "FunctorA" << endl;
}
};
struct FunctorB {
void operator() () {
cout << "FunctorB" << endl;
}
};
template<typename... Fs>
void apply_functors(Fs... fs) {
fs()...; // will not work - can only expand packs in certain situations (e.g. as funciton
}
int main(void) {
apply_functors(FunctorA(),FunctorB());
apply_functors(FunctorA());
apply_functors([]()->void{ cout << "Lambda" << endl; });
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是这不起作用,因为我们只允许在某些情况下 …
以下定义了一个min函数
template <typename T, typename U>
constexpr auto
min(T&& t, U&& u) -> decltype(t < u ? t : u)
{
return t < u ? t : u;
}
Run Code Online (Sandbox Code Playgroud)
有一个问题:它似乎写得完全合法
min(10, 20) = 0;
Run Code Online (Sandbox Code Playgroud)
这已经过Clang 3.5和g ++ 4.9的测试.
解决方案很简单,只是std::forward用来恢复参数的"rvalue-ness",即修改正文和decltype说
t < u ? std::forward<T>(t) : std::forward<U>(u)
Run Code Online (Sandbox Code Playgroud)
但是,我无法解释为什么第一个定义不会产生错误.
鉴于我的转发和普遍引用,两者的理解t和u演绎他们的论据类型,int&&当传递整数常量.但是,在正文中min,参数有名称,因此它们是左值.现在,条件运算符的真正复杂规则发挥作用,但我认为相关的是:
- E2 [和] E3都是相同类型的glvalues.在这种情况下,结果具有相同的类型和值类别.
因此,返回类型operator?:应该是int&&为好,应该不是吗?但是,(据我所知),Clang和g ++都 …
c++ conditional-operator rvalue-reference c++11 universal-reference