我必须格式化std::string用sprintf,并将其发送到文件流.我怎样才能做到这一点?
给出以下代码:
struct Window{
void show();
//stuff
}w1, w2, w3;
struct Widget{
void show();
//stuff
}w4, w5, w6;
struct Toolbar{
void show();
//stuff
}t1, t2, t3;
Run Code Online (Sandbox Code Playgroud)
我想要show一堆物品:
for (auto &obj : {w3, w4, w5, t1})
obj.show();
Run Code Online (Sandbox Code Playgroud)
然而,这不会编译,因为std::initializer_list<T>在for-loop中无法推断T,事实上并没有真正T适合的.我不想创建类型擦除类型,因为需要大量的代码和不必要的运行时开销.如何正确编写循环以便obj分别为概念列表中的每个项推导出类型?
我尝试实现C++ 14别名模板make_integer_sequence,这简化了类模板的创建integer_sequence.
template< class T, T... I> struct integer_sequence
{
typedef T value_type;
static constexpr size_t size() noexcept { return sizeof...(I) ; }
};
template< class T, T N>
using make_integer_sequence = integer_sequence< T, 0,1,2, ... ,N-1 >; // only for illustration.
Run Code Online (Sandbox Code Playgroud)
为了实现,make_integer_sequence我们需要一个辅助结构make_helper.
template< class T , class N >
using make_integer_sequence = typename make_helper<T,N>::type;
Run Code Online (Sandbox Code Playgroud)
实施make_helper并不太难.
template< class T, T N, T... I >
struct make_helper
{
typedef …Run Code Online (Sandbox Code Playgroud) 我的问题在于代码:
template<typename... Ts>
struct TupleOfVectors {
std::tuple<std::vector<Ts>...> tuple;
void do_something_to_each_vec() {
//Question: I want to do this:
// "for each (N)": do_something_to_vec<N>()
//How?
}
template<size_t N>
void do_something_to_vec() {
auto &vec = std::get<N>(tuple);
//do something to vec
}
};
Run Code Online (Sandbox Code Playgroud) 我有一段类似下面的c ++ 11代码:
switch(var) {
case 1: dosomething(std::get<1>(tuple));
case 2: dosomething(std::get<2>(tuple));
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法删除这个大型交换机?请注意,get<var>这不起作用,因为var不是常量,但我知道var在小范围内,即(0-20).
请注意,这里的要点是避免使用导致数组查找的数组...
编辑:
在性能问题上,讨论 了if和switch语句的函数数组的性能
出于我自己的目的,我不认为哪一个更好.
我做了以下元组:
我想知道如何迭代它?有tupl_size(),但阅读文档,我没有得到如何利用它.我也搜索了SO,但问题似乎就在附近Boost::tuple.
auto some = make_tuple("I am good", 255, 2.1);
Run Code Online (Sandbox Code Playgroud) 如果我想做迭代一个元组的事情,我不得不求助于疯狂的模板元编程和模板助手专业化.例如,以下程序将不起作用:
#include <iostream>
#include <tuple>
#include <utility>
constexpr auto multiple_return_values()
{
return std::make_tuple(3, 3.14, "pi");
}
template <typename T>
constexpr void foo(T t)
{
for (auto i = 0u; i < std::tuple_size<T>::value; ++i)
{
std::get<i>(t);
}
}
int main()
{
constexpr auto ret = multiple_return_values();
foo(ret);
}
Run Code Online (Sandbox Code Playgroud)
因为i不能const或我们无法实现它.但是for循环是一个可以静态计算的编译时构造.由于as-if规则,编译器可以自由地删除它,转换它,折叠它,展开它或者用它做任何他们想做的事情.但是为什么不能以constexpr方式使用循环呢?这段代码中没有任何东西需要在"运行时"完成.编译器优化就是证明.
我知道你可能会i在循环体内修改,但编译器仍然可以检测到它.例:
// ...snip...
template <typename T>
constexpr int foo(T t)
{
/* Dead code */
for (auto i = 0u; i < std::tuple_size<T>::value; ++i)
{
} …Run Code Online (Sandbox Code Playgroud) boost是否支持c ++ 11的std :: tuple的序列化?
我在/ boost/serialization /找不到tuple.hpp头文件
在某些情况下,for在编译时评估/展开循环可能是有用/必要的。例如,要遍历a的元素tuple,需要使用std::get<I>,这取决于模板int参数I,因此必须在编译时对其进行评估。使用编译递归可以解决一个特定的问题,例如此处,此处以及std::tuple 此处专门讨论的问题。
但是,我对如何实现通用编译时for循环感兴趣。
以下c++17代码实现了这个想法
#include <utility>
#include <tuple>
#include <string>
#include <iostream>
template <int start, int end, template <int> class OperatorType, typename... Args>
void compile_time_for(Args... args)
{
if constexpr (start < end)
{
OperatorType<start>()(std::forward<Args>(args)...);
compile_time_for<start + 1, end, OperatorType>(std::forward<Args>(args)...);
}
}
template <int I>
struct print_tuple_i {
template <typename... U>
void operator()(const std::tuple<U...>& x) { std::cout << std::get<I>(x) …Run Code Online (Sandbox Code Playgroud) c++ template-meta-programming variadic-templates c++17 c++20
我写了一个类multi_array,它是std::array多维度的扩展.
template <typename T, std::size_t... N>
class multi_array {
template <std::size_t... I, typename... Idx>
constexpr std::size_t linearized_index(meta::index_sequence<I...>,
Idx... idx) const {
std::size_t index = 0;
using unpack = std::size_t[];
(void)unpack{0UL,
((void)(index = (index + unpack{std::size_t(idx)...}[I]) *
meta::pack_element<I + 1, N...>::value),
0UL)...};
return index + unpack{std::size_t(idx)...}[sizeof...(idx) - 1];
}
// Storage
T m_data[meta::product<N...>::value];
//...
};
Run Code Online (Sandbox Code Playgroud)
我设法获得constexpr元素访问权限,但仅限于C++ 14.问题是功能linearized_index.它在编译时计算线性化索引.为了做到这一点,它以某种方式减少了索引的元组和维度的元组.对于这种减少,我需要在函数内部使用局部变量,但在C++ 11中不允许这样做.我的环境不允许使用C++ 14.我可以以某种方式重写此函数以使用C++ 11吗?
我已经准备了一个完整的(不是那么简单的)用C++编写的例子14.
#include <cstddef> // std::size_t
namespace meta {
// product
template <std::size_t...>
struct …Run Code Online (Sandbox Code Playgroud) c++ templates template-meta-programming variadic-templates c++11