我想创建一个静态分配2 ^ N字节数组的结构,但我不希望此结构的用户将此大小指定为指数.例:
my_stupid_array<char, 32> a1; // I want this!
my_stupid_array<char, 5> a2; // And not this...
Run Code Online (Sandbox Code Playgroud)
如何检查此模板参数是否为2的幂并警告用户有关于此的好消息?
我已经能够通过一个简单的模板检查这个:
template<int N>
struct is_power_of_two {
enum {val = (N >= 1) & !(N & (N - 1))};
};
Run Code Online (Sandbox Code Playgroud)
但是,我无法通过合理的消息警告用户.有任何想法吗?
编辑
修复了模棱两可的例子.
编辑
1确实是2的幂.修好了!:)
编辑
使用BOOST_STATIC_ASSERT,我收到此代码与GCC的编译错误:
template<int N>
struct is_power_of_two {
enum {val = (N >= 1) & !(N & (N - 1))};
BOOST_STATIC_ASSERT(val);
};
Run Code Online (Sandbox Code Playgroud)
错误
..\main.cpp:29:1: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
Run Code Online (Sandbox Code Playgroud)
编辑 …
在C++ 11中,您可以通过执行类似的操作来创建"类型别名"
template <typename T>
using stringpair = std::pair<std::string, T>;
Run Code Online (Sandbox Code Playgroud)
但这与您期望的模板typedef看起来有所不同:
template <typename T>
typedef std::pair<std::string, T> stringpair;
Run Code Online (Sandbox Code Playgroud)
所以这提出了一个问题 - 为什么他们需要提出一个新的语法?什么是旧的typedef语法不起作用?
我意识到最后一点没有编译,但为什么不能编译?
考虑以下类.
struct with_copy {
with_copy() = default;
with_copy(with_copy const&) {}
with_copy& operator=(with_copy const&) { return *this; }
};
struct foo {
with_copy c;
std::unique_ptr<int> p;
};
Run Code Online (Sandbox Code Playgroud)
with_copy有一个拷贝构造函数?是.它是明确定义的.with_copy有一个移动构造函数?不可以.显式复制构造函数阻止生成它.with_copy有删除的移动构造函数?不.没有移动构造函数与删除构造函数不同.删除的移动构造函数会尝试将格式错误而不是退化移动到副本.with_copy复制吗?是.其复制构造函数用于复制.with_copy可移动的?是.它的复制构造函数用于移动.......现在是棘手的.
foo有一个拷贝构造函数?是.它有一个删除的,因为它的默认定义将由于调用unique_ptr已删除的复制构造函数而格式不正确.foo有一个移动构造函数?GCC说是的,clang说没有.foo有删除的移动构造函数?海湾合作委员会和铿锵声说不.foo复制吗?不会.它的复制构造函数被删除.foo可移动的?GCC说是的,clang说没有.(当考虑赋值而不是构造时,行为类似.)
据我所知,海湾合作委员会是正确的.foo应该有一个移动构造函数,在每个成员上执行移动,在这种with_copy情况下退化为副本.Clang的行为似乎很荒谬:我有一个有两个可移动成员的聚合体,但我的聚合物是一个不可移动的砖块.
谁是对的?
c++ user-defined-functions implicit-declaration move-semantics c++11
我想知道为什么使用the创建一个最小堆priority_queue,std::greater应该使用?
std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;
Run Code Online (Sandbox Code Playgroud)
对我来说,由于最小的值总是位于堆的顶部,所以应用的类应该是 std::less
更新:
另一方面,由于priority_queue(max heap)的默认行为是在顶部保持最大值,因此我认为std::greater应该用于最大堆创建而不是用于创建最小堆
我在看这个源代码
template<char... digits>
struct conv2bin;
template<char high, char... digits>
struct conv2bin<high, digits...> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0') * (1 << sizeof...(digits)) +
conv2bin<digits...>::value;
};
template<char high>
struct conv2bin<high> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0');
};
template<char... digits>
constexpr int operator "" _b() {
return conv2bin<digits...>::value;
}
int array[1010_b];
Run Code Online (Sandbox Code Playgroud)
我想知道这是否是有效的C++.
template<char high, char... digits> …Run Code Online (Sandbox Code Playgroud) c++ static-assert user-defined-literals variadic-templates c++11
具体来说,我有一个目前使用vector和push_back的类.我想跟踪的向量中有一个元素.推回向量可能会使迭代器无效,所以我保持其索引.使用索引再次找到迭代器很便宜.我不能保留矢量,因为我不知道将插入多少项.
我已经考虑过将数据结构作为模板参数,也许可以使用list.在这种情况下,从索引中查找迭代器不是一个简单的操作.由于推回列表不会使现有元素的迭代器无效,我可以只存储这个迭代器.
但是,我如何编写一个容易处理这两种情况的泛型类?
如果我可以找出push_back是否会使迭代器无效,我可以存储迭代器并在每次push_back之后通过存储操作之前的距离来更新它.
我有这个代码生成一个大小为4的数组的幂集(数字只是一个例子,更少的组合写...).
#define ARRAY_SIZE 4
unsigned int i, j, bits, i_max = 1U << ARRAY_SIZE;
int array[ARRAY_SIZE];
for (i = 0; i < i_max ; ++i) {
for (bits = i, j = 0; bits; bits >>= 1, ++j) {
if (bits & 1)
printf("%d", array[j]);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
{}
{1}
{2}
{1, 2}
{3}
{1, 3}
{2, 3}
{1, 2, 3}
{4}
{1, 4}
{2, 4}
{1, 2, 4}
{3, 4}
{1, 3, 4}
{2, 3, 4}
{1, 2, 3, …Run Code Online (Sandbox Code Playgroud) 我最近在玩CRTP的时候遇到的东西让我感到惊讶,因为它与c ++ 1y函数一起使用,其类型是推导出来的.以下代码有效:
template<typename Derived>
struct Base
{
auto foo()
{
return static_cast<Derived*>(this)->foo_impl();
}
};
struct Derived:
public Base<Derived>
{
auto foo_impl()
-> int
{
return 0;
}
};
int main()
{
Derived b;
int i = b.foo();
(void)i;
}
Run Code Online (Sandbox Code Playgroud)
我假设返回类型Base<Derived>::foo是decltype返回的表达式的一个,但如果我修改这样的函数foo:
auto foo()
-> decltype(static_cast<Derived*>(this)->foo_impl())
{
return static_cast<Derived*>(this)->foo_impl();
}
Run Code Online (Sandbox Code Playgroud)
此代码不再起作用,我收到以下错误(来自GCC 4.8.1):
||In instantiation of 'struct Base<Derived>':|
|required from here|
|error: invalid static_cast from type 'Base<Derived>* const' to type 'Derived*'|
||In function 'int main()':|
|error: …Run Code Online (Sandbox Code Playgroud) 我的理解是constexpr类类型的全局变量几乎无法使用,因为
必须在每个TU中定义这样的对象,因为constexpr不允许对象的前向声明.
默认链接static会导致在内联函数中命名对象(ODR使用与否)以违反ODR,因为相应的inline定义具有不同的含义.
extern constexpr如果对象是ODR使用的,则每个TU的一个定义的声明将违反ODR规则,这在对其进行引用时发生.
this参数,即使它已被成员函数使用.extern constexpr即使没有使用ODR,也会声明对象,GCC和Clang都会抱怨ODR违规(多个定义).这都是正确的吗?有没有办法让一个constexpr全局类类型没有包装在一个inline函数中?
在我的申请中,我有以下要求 -
数据结构将仅使用一些值(不是键/值对)填充一次.值可能会重复,但我希望数据结构只存储一次.
我将通过上面创建的数据结构的所有元素迭代100次.元素在迭代中出现的顺序并不重要.
约束1表明我将不得不使用set或unordered_set,因为数据不是键值对的形式.
现在set插入比unordered_set插入更昂贵,但数据结构只在我的程序开头填充一次.
我相信决定因素是我可以多快地迭代数据结构的所有元素.我不确定set或unordered_set对于此目的是否会更快.我相信标准没有提到这个事实,因为这个操作对于任一数据结构都是O(n).但我想知道iterator.next()哪个数据结构会更快.