以下代码如何工作?
typedef char (&yes)[1];
typedef char (&no)[2];
template <typename B, typename D>
struct Host
{
operator B*() const;
operator D*();
};
template <typename B, typename D>
struct is_base_of
{
template <typename T>
static yes check(D*, T);
static no check(B*, int);
static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};
//Test sample
class Base {};
class Derived : private Base {};
//Expression is true.
int test[is_base_of<Base,Derived>::value && !is_base_of<Derived,Base>::value];
Run Code Online (Sandbox Code Playgroud)
请注意,这B是私人基地.这是如何运作的?
注意operator B*()是const.它为什么如此重要?
为什么template<typename T> static yes …
我正在创建一个函数(可能是成员函数,而不是它很重要......也许它确实?)需要接受未知数量的参数,但我希望它们都是相同的类型.我知道我可以传入数组或向量,但我希望能够直接接受args列表而无需额外的结构甚至是额外的括号.看起来variadic函数本身并不是类型安全的,我不知道如何使用这个w/variadic模板函数.这基本上就是我的目标(更可能不是正确的代码,完全不是为了获取龙的列表,哈哈):
//typedef for dragon_list_t up here somewhere.
enum Maiden {
Eunice
, Beatrice
, Una_Brow
, Helga
, Aida
};
dragon_list_t make_dragon_list(Maiden...) {
//here be dragons
}
Run Code Online (Sandbox Code Playgroud)
要么
template<Maiden... Maidens> dragon_list_t make_dragon_list(Maidens...) {
//here be dragons
}
Run Code Online (Sandbox Code Playgroud)
用法
dragon_list_t dragons_to_slay
= make_dragon_list(Maiden.Eunice, Maiden.Helga, Maiden.Aida)
;
Run Code Online (Sandbox Code Playgroud)
尝试了类似于上面的一些事情,没有骰子.建议?我可能做出明显的疏忽?我知道这样做可能不是一件大事:
dragon_list_t make_dragon_list(std::array<Maiden> maidens) {
//here be dragons.
}
dragon_list_t dragons_to_slay
= make_dragon_list({Maiden.Eunice, Maiden.Helga, Maiden.Aida})
;
Run Code Online (Sandbox Code Playgroud)
但如果可能的话,我宁愿能够以第一种方式做到这一点.
有人可以向我解释为什么C++,至少据我所知,没有实现一个强类型的省略号函数,这是有效的:
void foo(double ...) {
// Do Something
}
Run Code Online (Sandbox Code Playgroud)
这意味着,简单地说:'用户可以将可变数量的术语传递给foo函数,但是,所有术语必须是双倍的'
我正在创建一个可变参数模板.
假设我有这样的事情:
template<typename T, T ... Numbers>
class Sequence final {
// Unpack parameter pack into a constexpr array
constexpr static T count = sizeof...(Numbers);
constexpr static T numbers[count] = { Numbers... };
// ...
}
Run Code Online (Sandbox Code Playgroud)
可以将此类的实例实例化为:
Sequence<uint32_t, 1, 2, 3, 42, 25> seq;
Run Code Online (Sandbox Code Playgroud)
我想使用,以确保在编译时static_assert的numbers参数包中只包含具体的数字.为了这个例子,让我们说我只想允许0或1.
所以我想做一些像:
for (size_t i = 0; i < count; i++) {
static_assert(numbers[i] == 1 || numbers[i] == 0, "Only ones and zeroes are allowed.");
}
Run Code Online (Sandbox Code Playgroud)
但显然,static_assert …
前言.我试图对C++模板元编程有一些更深入的了解,似乎我被卡住了...我正在编写一个库,我们将用它来进行二进制数据[de]序列化.正在解压缩的数据的预期结构在某种程度上是已知的,并且使用这些知识(1)验证数据(2)跳过不相关的部分以及(3)将数据直接解压缩到编译时已知的结构中似乎是合理的. - 用于避免不必要的复制并使客户端代码看起来更清晰.
因此,例如,我想实现一个解包数组的函数(数组可以包含异构数据,如JSON).为简单起见,假设数组具有固定大小,并且没有嵌套.
实际问题我想写一个函数,它将包含一个包含序列化数据的输入缓冲区(或一个流 - 在我们的上下文中无关紧要)和一个std::tuple包含输出的左值(参数包是一个更糟糕的选择,因为我最终必须处理嵌套问题.因此,我首先需要检查一个元组中的所有类型是否适合解包器,并提供相关的错误消息,如果不是.
所以代码是这样的:
template<typename T>
struct is_integral_lvalue : std::integral_constant<bool,
std::is_lvalue_reference<T>::value &&
std::is_integral<T>::value &&
(sizeof(T) == 4 || sizeof(T) == 8)>
{
};
/* ... */
template<typename TInputBuffer, typename... TDest>
static TRet unpack_int_tuple(TInputBuffer src_buf, std::tuple<TDest...> &&dest) noexcept(is_noexcept)
{
static_assert(typelist::all_are<is_integral_lvalue, TDest...>::value,
"All types in a tuple must be integral lvalue-references");
/* do unpacking */
}
Run Code Online (Sandbox Code Playgroud)
这种情况is_integral_constant可能有些武断.这就是为什么all_are模板可以使用任何一元谓词的原因.问题是:我应该写什么typelist::all_are(也许,我应该在上面的代码中解决什么才能编写这样的代码all_are)?
一个工作的例子当然是理想的,但如果它们有用,我会很感激一般的想法/建议.
限制我的目标不仅仅是实现这个功能,而是要了解它是如何工作的(像"使用boost :: mpl"或"boost :: hana"这样的解决方案是不合适的).我们使用的不太相关的东西越多越好.最好是代码应该是C++ 11(我们还没准备好在生产中使用C++ 1y/GCC …
考虑bool技巧来检查一堆类型是否都是相同的类型:
template<typename Type, typename... Types>
static constexpr bool allOf = std::is_same<
std::integer_sequence<bool, true, std::is_same<Type, Types>::value...>,
std::integer_sequence<bool, std::is_same<Type, Types>::value..., true>
>::value;
Run Code Online (Sandbox Code Playgroud)
例如,可以使用它来检查所有参数是否为int值:
template<typename... Args>
void f(Args&&... args) {
static_assert(allOf<int, Args...>, "!");
// ...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将它与给定模板模板参数的特化一起使用?
例如,使用以下代码:
template<typename> struct S {};
template<typename... Args>
void f(Args&&... args) {
static_assert(allOf<S, Args...>, "!");
// ...
}
Run Code Online (Sandbox Code Playgroud)
该allOf变量应定义为:
template<template<typename> class Type, typename... Types>
static constexpr bool allOf = ???;
Run Code Online (Sandbox Code Playgroud)
我想检查每个T在Types的形式是一个专业化S<U>,不知道什么事U.
可能吗?
如何检查可变参数模板声明中的所有类型都可以转换为size_t:
// instantiate only if extents params are all convertible to size_t
template<typename T, size_t N>
template<typename... E>
Array<T,N>::Array(E... extents) {
constexpr size_t n = sizeof...(extents);
static_assert(n == N, "Dimensions do not match");
// code for handling variadic template parameters corresponding to dimension sizes
}
Run Code Online (Sandbox Code Playgroud)
具有以下用法:
Array<double, 2> a(5,6); // OK 2-D array of 5*6 values of doubles.
Array<int, 3> a(2,10,15) // OK 3-D array of 2*10*15 values of int.
Array<int, 2> a(2, "d") // Error: "d" is not a …Run Code Online (Sandbox Code Playgroud) c++ ×7
c++11 ×4
templates ×3
c++14 ×1
ellipsis ×1
fold ×1
overloading ×1
parameters ×1
type-traits ×1