这个问题仅用于测试目的,仅此而已.
我目前正在尝试使用不同数量的参数存储函数指针(这些参数可以有不同的类型).
基本上,我在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) 如果我定义一个接受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) 我正在尝试编写一个函数,该函数以一个形式返回一个可变参数包的子集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) 通常情况下,如果我有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
这可能吗 ?一个简单的办法是同时具有Foo和Bar一些类型继承,也就是说Baz,并已重载方法返回一个Baz,你转换回Foo或Bar...
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)
但这里的问题是你必须写:
目标是编写单个类,方法或宏,我们可以调用一个函数(并传递任何参数),但调用传入的对象的正确构造函数.这可能吗 ?
这个问题的目的是简单地探究是否可以在C++中做这样的事情.请不要提出共享指针,独特的指针,使用新的陷阱,因为这是偏离主题.
编辑:我想只使用STL,并避免使用像Boost ....
在这样的函数模板中
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
std::vector几乎所有其他容器都有一种非常方便的边界检查方法:at(). std::span显然没有那个。
at()?我遇到了一个代码,用在哪里std::forward。我已经在Google上搜索了很长时间,但无法了解其真正目的和用途。
我在stackoverflow中看到过类似的线程,但仍不清楚。有人可以用一个简单的例子来解释吗?
PS:我浏览了此页面,但仍然无法欣赏它的使用。请不要将这个问题标记为重复,而是尝试帮助我。
在下面的代码中,为什么我应该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) 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根据参考折叠规则很容易理解,但为什么模板函数传递v给reference()lvalue?
在以下代码中,使用的好处是&&什么?该代码来自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)