我正在寻找一种方法来从模板参数包中删除(现在让我们说所有出现的)一个类型.最终结果将是一个如下所示的结构:
template<typename T, typename...Ts>
struct RemoveT
{
using type = /* a new type out of Ts that does not contain T */
}
Run Code Online (Sandbox Code Playgroud)
假设边缘情况RemoveT<int, int>
将通过返回来处理void
(不在后面的代码中处理).我的初始设计看起来像这样:
// --------------------------------------------------------------
// 1. A "way" of typedefing variadic number of types ------------
template<typename...Ts>
struct pack {
using type = Ts;
};
// --------------------------------------------------------------
// --------------------------------------------------------------
template<typename T, typename...Ts> struct RemoveT;
template<typename T, typename T1, typename...Ts>
struct RemoveT {
using type = typename pack<T1, typename RemoveT<T, …
Run Code Online (Sandbox Code Playgroud) c++ templates template-meta-programming variadic-templates c++11
说我要来存储三种类型的tuple
:int
,float
和std::vector<double>
如果我抛开后续界面的问题,就这样做
tuple<int, float, vector<int>> t;
Run Code Online (Sandbox Code Playgroud)
与此有任何不同
tuple<vector<int>, int, float> t;
Run Code Online (Sandbox Code Playgroud)
由于tuple
作为一类可变参数的实现,我期望生成的类有不同的布局,但它有什么关系吗?在将类型放入a tuple
(例如,放置最大的第一个等)时,是否还要考虑任何优化注意事项?
是否有一种技术/最佳风格可以为某些类型分组类模板特化?
一个例子:假设我有一个类模板Foo
,我需要为排版设置相同的专用模板
A = { Line, Ray }
Run Code Online (Sandbox Code Playgroud)
而另一种方式是排版B.
B = { Linestring, Curve }
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
#include <type_traits>
using namespace std;
// 1st group
struct Line {};
struct Ray {};
// 2nd group
struct Curve {};
struct Linestring {};
template<typename T, typename Groupper=void>
struct Foo
{ enum { val = 0 }; };
// specialization for the 1st group
template<typename T>
struct Foo<T, typename enable_if<
is_same<T, Line>::value ||
is_same<T, Ray>::value
>::type>
{ …
Run Code Online (Sandbox Code Playgroud) 以下代码无法编译:
#include <iostream>
template<typename F, typename ...Args>
static auto wrap(F func, Args&&... args)
{
return func(std::forward<Args>(args)...);
}
void f1(int, char, double)
{
std::cout << "do nada1\n";
}
void f2(int, char='a', double=0.)
{
std::cout << "do nada2\n";
}
int main()
{
wrap(f1, 1, 'a', 2.);
wrap(f2, 1, 'a');
}
Run Code Online (Sandbox Code Playgroud)
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In instantiation of 'auto wrap(F, Args&& ...) [with F = void(*)(int, char, double); Args = {int, char}]':
main.cpp:22:20: required from …
Run Code Online (Sandbox Code Playgroud) 即使const成员函数将修改成员的值,以下将编译.怎么会这样 ?
#include <iostream>
struct foo
{
std::string &str;
foo(std::string &other) : str(other) {}
void operator()(std::string &some) const
{
str += some;
}
};
int main()
{
std::string ext("Hello");
foo a{ ext };
std::string more(" world!");
a(more);
cout << a.str;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我注意到将class
or struct
关键字添加到原本需要向前声明的类型,就好像该类型是向前声明的那样:
// struct Test; forward declaration commented
void* foo(struct Test* t) // C style function parameter - This works !
{
return t;
}
Run Code Online (Sandbox Code Playgroud)
我没有意识到这一点.我想知道它是标准的C++还是扩展,以及struct
参数之前的关键字是作为前向声明还是其他机制起作用.
此外,在这样的用法之后,"next"函数可以使用该类型而不需要添加任何关键字:
void* oof(Test* t);
Run Code Online (Sandbox Code Playgroud)
在C++ 11中,可以声明一个类似的函数
auto times2(double num) -> double; // A
Run Code Online (Sandbox Code Playgroud)
并定义它
double times2(double num) { // B
return num*2;
}
Run Code Online (Sandbox Code Playgroud)
这对A, B
也可以反过来混合.
C++ 14引入了第三种方式
auto times2(double num) { // C
return num;
}
Run Code Online (Sandbox Code Playgroud)
C
可以在声明/定义对中混合使用吗?A / B
可以C
单独作为签名(当尚未提供功能的主体时)?
// waiting for the definition to provide info on return type
auto times2(double);
Run Code Online (Sandbox Code Playgroud)我想要一个像std::transform
元组一样的函数.基本上要实现的功能是
template<size_t From, size_t To, class Tuple, class Func>
void tuple_transform(Tuple&& source, Tuple&& target, Func f)
{
// elements <From, To> of `target` ti become `f(si)`, where
// si is the corresponding element of `source`
};
Run Code Online (Sandbox Code Playgroud)
我认为,要实现这一点,我需要一个编译时整数范围结构,的概括std::index_sequence
,我已经实现了它在这里用cti::range
.我也相信这种类型的编译时间遍历在这里是理想的:
template<class Func, class Tuple, size_t...Is>
void for_each_in_tuple(Func f, Tuple&& tuple, std::index_sequence<Is...>){
using expander = int[];
(void)expander { 0, ((void)f(std::get<Is>(std::forward<Tuple>(tuple))), 0)... };
}
template<class Func, class Tuple>
void for_each_in_tuple(Func f, Tuple&& tuple){ …
Run Code Online (Sandbox Code Playgroud) 我下周将在C++ 11/14上上课,需要验证我的设计工具是最新的,并且实际上可以编译C++ 11/14.
我可以用什么最简单的代码来验证我是否可以在我的Linux机器上编译和执行C++ 11/14代码?我知道我需要GCC 4.9.X或更好,但我想确保在我出现之前一切都在疯狂.
谢谢您的帮助.
我在Effective Modern C++中看到的代码片段巧妙地实现了创建函数计时器的工具原理:
auto timeFuncInvocation =
[](auto&& func, auto&&... params)
{
start timer;
std::forward<decltype(func)>(func)(
std::forward<decltype(params)>(params)...);
stop timer and record elapsed time;
};
Run Code Online (Sandbox Code Playgroud)
我的问题是关于 std::forward<decltype(func)>(func)(...
对于在lambda表达式中使用熟悉的模板语法,这似乎是一个很好的用例,以防我们想要使计时器类型成为编译时常量.