相关疑难解决方法(0)

将函数指针转换为void(*)(),然后重铸为原始类型

这个问题仅用于测试目的,仅此而已.

我目前正在尝试使用不同数量的参数存储函数指针(这些参数可以有不同的类型).

基本上,我在C++ 11中编写了以下代码片段:

#include <functional>
#include <iostream>

void fct(int nb, char c, int nb2, int nb3) {
  std::cout << nb << c << nb2 << nb3 << std::endl;
}

template <typename... Args>
void call(void (*f)(), Args... args) {
  (reinterpret_cast<void(*)(Args...)>(f))(args...);
}

int main(void) {
  call(reinterpret_cast<void(*)()>(&fct), 42, 'c', 19, 94);
}
Run Code Online (Sandbox Code Playgroud)

我将void(*)(int, char, int, int)函数指针转换为通用void(*)()函数指针.然后,通过使用可变参数模板参数,我只需将函数指针重新设置为其原始类型,并使用一些参数调用该函数.

此代码编译并运行.大多数时候,它显示出良好的价值.但是,这段代码在Mac OS下给我一些Valgrind错误(关于未初始化的值),它有时会显示一些意外的垃圾.

==52187== Conditional jump or move depends on uninitialised value(s)
==52187==    at 0x1004E4C3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==52187==    by 0x1002D8B96: __sfvwrite (in …
Run Code Online (Sandbox Code Playgroud)

c++ pointers function-pointers c++11

7
推荐指数
1
解决办法
2843
查看次数

Rvalue参考参数和模板函数

如果我定义一个接受rvalue引用参数的函数:

template <typename T>
void fooT(T &&x) {}
Run Code Online (Sandbox Code Playgroud)

我可以调用它,使用GCC 4.5,无论使用哪种a,ar或者arr:

int a, &ar = a, &&arr = 7;
fooT(a); fooT(ar); fooT(arr);
Run Code Online (Sandbox Code Playgroud)

但是,调用类似的非模板函数,

void fooInt(int &&x) {}
Run Code Online (Sandbox Code Playgroud)

这三个参数中的任何一个都会失败.我正准备加强我的知识forward,但这已经让我失去了理智.也许它是GCC 4.5; 我很惊讶地发现Rvalue References简介中的第一个例子也给出了一个编译错误:

A a;
A&& a_ref2 = a;  // an rvalue reference
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference c++11

6
推荐指数
2
解决办法
3125
查看次数

删除右值,保持左值引用(标准类型特征可用吗?)

我正在尝试编写一个函数,该函数以一个形式返回一个可变参数包的子集std::tuple.理想情况下,该函数不应具有运行时开销(没有不必要的副本),并且应该允许用户访问lvalue引用并修改它们.

应保持值类型,lvalue引用和const lvalue引用.Temporaries(rvalue引用)应该"转换"为值类型,以避免创建无效引用(对临时引用的引用).

期望结果的示例:

int lr = 5;
const int& clr = lr;

auto t = make_subpack_tuple(lr, clr, 5);

static_assert(is_same
<
    decltype(t), 
    std::tuple<int&, const int&, int>
>{}, "");

// Ok, modifies lr:
std::get<0>(t) = 10;

// Compile-time error, intended:
// std::get<1>(t) = 20;

// Ok, 5 was moved into the tuple:
std::get<2>(t) = 30;
Run Code Online (Sandbox Code Playgroud)

示例不完整实施:

template<typename... Ts>
auto make_subpack_tuple(Ts&&... xs)
{
    return std::tuple
    <
        some_type_trait<decltype(xs)>...
    >
    (
        std::forward<decltype(xs)>(xs)...
    );
} …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits rvalue-reference perfect-forwarding c++14

6
推荐指数
1
解决办法
489
查看次数

是否可以创建一个可用于创建任何类的"新"实例的泛型方法或类?

通常情况下,如果我有a Foo或a Bar,我会做类似的事情:

Foo* foo = new Foo();

Bar* bar = new Bar(2,3,5);
Run Code Online (Sandbox Code Playgroud)

有没有办法使用模板或宏,我可以构建一个函数,这样我可以做类似的事情:

Foo* foo = MyAwesomeFunc(Foo);
Bar* bar = MyAwesomeFunc(Bar,2,3,5); 
Run Code Online (Sandbox Code Playgroud)

实际的方法签名MyAwesomeFunc对我来说并不重要.

Foo并且Bar不需要以任何可能的方式相关,并且可能具有完全不同的构造函数.此外,我可能希望将来支持任意数量的类,而无需实际修改代码MyAwesomeFunc

这可能吗 ?一个简单的办法是同时具有FooBar一些类型继承,也就是说Baz,并已重载方法返回一个Baz,你转换回FooBar...

Baz* MyAwesomeFunc(){
    return new Foo();
}

Baz* MyAwesomeFunc(int a,int b,int c){
    return new Bar(a,b,c);
}
Run Code Online (Sandbox Code Playgroud)

但这里的问题是你必须写:

  1. 支持每个类的方法
  2. 并为每种构造函数签名.

目标是编写单个类,方法或宏,我们可以调用一个函数(并传递任何参数),但调用传入的对象的正确构造函数.这可能吗 ?

这个问题的目的是简单地探究是否可以在C++中做这样的事情.请不要提出共享指针,独特的指针,使用新的陷阱,因为这是偏离主题.

编辑:我想只使用STL,并避免使用像Boost ....

c++ templates variadic-templates perfect-forwarding c++11

6
推荐指数
2
解决办法
721
查看次数

为什么 std::forward 需要转发引用

在这样的函数模板中

template <typename T>
void foo(T&& x) {
  bar(std::forward<T>(x));
}
Run Code Online (Sandbox Code Playgroud)

如果用右值引用调用,x内部不是右值引用吗?如果 foo 是用左值引用调用的,则无论如何都不需要强制转换,因为在. 也将被推导为左值引用类型,因此不会改变.foofooxfooTstd::forward<T>x

我使用boost::typeindex和不使用std::forward<T>.

#include <iostream>
#include <utility>

#include <boost/type_index.hpp>

using std::cout;
using std::endl;

template <typename T> struct __ { };

template <typename T> struct prt_type { };
template <typename T>
std::ostream& operator<<(std::ostream& os, prt_type<T>) {
  os << "\033[1;35m" << boost::typeindex::type_id<T>().pretty_name()
     << "\033[0m";
  return os;
}

template <typename T>
void foo(T&& x) {
  cout << prt_type<__<T>>{} …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics perfect-forwarding c++11 forwarding-reference

6
推荐指数
1
解决办法
1322
查看次数

如何使用 std span 进行边界检查?

std::vector几乎所有其他容器都有一种非常方便的边界检查方法:at(). std::span显然没有那个。

c++ outofrangeexception c++20 std-span

6
推荐指数
1
解决办法
1700
查看次数

在C ++中使用std :: forward

我遇到了一个代码,用在哪里std::forward。我已经在Google上搜索了很长时间,但无法了解其真正目的和用途。

我在stackoverflow中看到过类似的线程,但仍不清楚。有人可以用一个简单的例子来解释吗?

PS:我浏览了此页面,但仍然无法欣赏它的使用。请不要将这个问题标记为重复,而是尝试帮助我。

c++ std c++11

5
推荐指数
2
解决办法
1815
查看次数

我为什么要使用std :: forward?

在下面的代码中,为什么我应该std::forward在传递参数时使用?

class Test {
  public:
  Test() {
      std::cout << "ctor" << std::endl;
  }
  Test(const Test&) {
      std::cout << "copy ctor" << std::endl;
  }
  Test(const Test&&) {
      std::cout << "move ctor" << std::endl;
  }
};

template<typename Arg>
void pass(Arg&& arg) {
    // use arg..
    return; 
}

template<typename Arg, typename ...Args>
void pass(Arg&& arg, Args&&... args)
{
    // use arg...
    return pass(args...); // why should I use std::forward<Arg>(args)... ?
}

int main(int argc, char** argv)
{
    pass(std::move<Test>(Test()));

    return 0;
} …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

5
推荐指数
1
解决办法
3831
查看次数

为什么右值参考传递为左值参考?

pass()引用参数并将其传递给reference,但是实际上调用了一个rvalue参数reference(int&)而不是reference(int &&),这里是我的代码片段:

#include <iostream>
#include <utility>
void reference(int& v) {
    std::cout << "lvalue" << std::endl;
}
void reference(int&& v) {
    std::cout << "rvalue" << std::endl;
}
template <typename T>
void pass(T&& v) {
    reference(v);
}
int main() {
    std::cout << "rvalue pass:";
    pass(1);

    std::cout << "lvalue pass:";
    int p = 1;
    pass(p);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

rvalue pass:lvalue
lvalue pass:lvalue
Run Code Online (Sandbox Code Playgroud)

因为p根据参考折叠规则很容易理解,但为什么模板函数传递vreference()lvalue?

c++

5
推荐指数
2
解决办法
737
查看次数

此代码中&amp;&amp;的优点是什么?

在以下代码中,使用的好处是&&什么?该代码来自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)

c++ universal-reference c++14

5
推荐指数
1
解决办法
313
查看次数