相关疑难解决方法(0)

C++ 03中的完美转发

如果你有这个功能

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?

c++ forwarding c++03

24
推荐指数
1
解决办法
4079
查看次数

C++将简单值转换为字符串

现在我用下面的一段代码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[]变量.

有一种简单的方法可以为这个问题提供优雅的解决方案吗?

c++ stringstream string-conversion c++11

22
推荐指数
4
解决办法
4864
查看次数

无法命名的C++类型

在阅读维基百科关于decltype的页面时,我很好奇这个陈述,

其[decltype]的主要用途是在通用编程中,通常很难甚至不可能命名依赖于模板参数的类型.

虽然我可以理解该语句的难点部分,但是需要命名一个无法在C++ 03下命名的类型的示例是什么?

编辑:我的观点是,因为C++中的所有内容都有类型声明.为什么会出现无法命名类型的情况?此外,是不是设计用于产生类型信息的特质类?特质课可以替代decltype吗?

c++ templates types decltype c++11

20
推荐指数
2
解决办法
783
查看次数

为什么必须模仿完美的转发功能?

为什么以下代码有效:

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.

c++ perfect-forwarding c++11

18
推荐指数
1
解决办法
3755
查看次数

什么时候应该使用前进和移动?

我有一个操作矢量的代码:

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)

c++ c++11

16
推荐指数
3
解决办法
1630
查看次数

如何通过引用将函数绑定到对象?

我有以下代码将成员函数绑定到类的实例:

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&&(如图所示这里)如何工作的呢?

有人可以解释一下吗?

c++ stdbind

15
推荐指数
2
解决办法
6627
查看次数

(优化?)关于GCC std :: thread的Bug

在测试某些功能的同时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)

multithreading clang c++11 gcc4.7

14
推荐指数
1
解决办法
555
查看次数

使用可变参数模板在C++中包装函数指针

问题

我有一个号码的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)

这是我到目前为止所尝试的:

解决方案1

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)

c++ templates function-pointers variadic-templates c++11

14
推荐指数
1
解决办法
6798
查看次数

可变函数接受函数/可调用对象

问题

我希望创建一个函数,它接受任意数量的仿函数对象,或者更通常只是可调用对象(不同类型),并将它们应用于内部数据结构.该函数将在我的代码中的不同点使用不同数量的仿函数.

而不是使不同的版本接受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)

但是这不起作用,因为我们只允许在某些情况下 …

c++ functor variadic-templates c++11

13
推荐指数
2
解决办法
828
查看次数

为什么这个函数在给定rvalue参数的情况下返回左值引用?

以下定义了一个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)

但是,我无法解释为什么第一个定义不会产生错误.


鉴于我的转发和普遍引用,两者的理解tu演绎他们的论据类型,int&&当传递整数常量.但是,在正文中min,参数有名称,因此它们是左值.现在,条件运算符真正复杂规则发挥作用,但我认为相关的是:

  • E2 [和] E3都是相同类型的glvalues.在这种情况下,结果具有相同的类型和值类别.

因此,返回类型operator?:应该是int&&为好,应该不是吗?但是,(据我所知),Clang和g ++都 …

c++ conditional-operator rvalue-reference c++11 universal-reference

13
推荐指数
1
解决办法
899
查看次数