小编Tem*_*Rex的帖子

如何检查模板参数是否为2的幂?

我想创建一个静态分配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)

http://ideone.com/cMfEf

编辑 …

c++ templates static-assert constexpr c++11

16
推荐指数
3
解决办法
4170
查看次数

模板typedef的新"使用"语法解决了什么问题?

在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语法不起作用?

我意识到最后一点没有编译,但为什么不能编译?

c++ templates typedef c++11 template-aliases

16
推荐指数
2
解决办法
542
查看次数

为什么既没有使用clang声明也没有删除移动构造函数?

考虑以下类.

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

16
推荐指数
2
解决办法
1362
查看次数

使用`std :: greater`通过`priority_queue`创建最小堆的原因

我想知道为什么使用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应该用于最大堆创建而不是用于创建最小堆

c++ heap priority-queue min-heap c++11

16
推荐指数
2
解决办法
2846
查看次数

我在C++ 11中从未见过的代码

我在看这个源代码

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

15
推荐指数
1
解决办法
1156
查看次数

当数据结构是模板参数时,如何判断操作是否会使迭代器失效?

具体来说,我有一个目前使用vector和push_back的类.我想跟踪的向量中有一个元素.推回向量可能会使迭代器无效,所以我保持其索引.使用索引再次找到迭代器很便宜.我不能保留矢量,因为我不知道将插入多少项.

我已经考虑过将数据结构作为模板参数,也许可以使用list.在这种情况下,从索引中查找迭代器不是一个简单的操作.由于推回列表不会使现有元素的迭代器无效,我可以只存储这个迭代器.

但是,我如何编写一个容易处理这两种情况的泛型类?

如果我可以找出push_back是否会使迭代器无效,我可以存储迭代器并在每次push_back之后通过存储操作之前的距离来更新它.

c++ containers templates iterator invalidation

15
推荐指数
1
解决办法
205
查看次数

由比特生成的功率集

我有这个代码生成一个大小为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)

c++ algorithm bit-manipulation subset powerset

15
推荐指数
1
解决办法
3285
查看次数

CRTP和c ++ 1y返回类型推导

我最近在玩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>::foodecltype返回的表达式的一个,但如果我修改这样的函数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)

c++ crtp c++11 return-type-deduction c++14

15
推荐指数
1
解决办法
1104
查看次数

constexpr类的全球类型

我的理解是constexpr类类型的全局变量几乎无法使用,因为

  • 必须在每个TU中定义这样的对象,因为constexpr不允许对象的前向声明.

  • 默认链接static会导致在内联函数中命名对象(ODR使用与否)以违反ODR,因为相应的inline定义具有不同的含义.

  • extern constexpr如果对象是ODR使用的,则每个TU的一个定义的声明将违反ODR规则,这在对其进行引用时发生.

    • 引用隐式this参数,即使它已被成员函数使用.
    • 如果您尝试通过引用传递对象,显然会发生这种情况.
    • 如果您尝试按值传递对象也会发生这种情况,该值隐式使用副本或移动构造函数,根据定义,它通过引用传递.
    • 如果extern constexpr即使没有使用ODR,也会声明对象,GCC和Clang都会抱怨ODR违规(多个定义).

这都是正确的吗?有没有办法让一个constexpr全局类类型没有包装在一个inline函数中?

c++ global one-definition-rule constexpr c++11

15
推荐指数
1
解决办法
1000
查看次数

set vs unordered_set用于最快的迭代

在我的申请中,我有以下要求 -

  1. 数据结构将仅使用一些值(不是键/值对)填充一次.值可能会重复,但我希望数据结构只存储一次.

  2. 我将通过上面创建的数据结构的所有元素迭代100次.元素在迭代中出现的顺序并不重要.

约束1表明我将不得不使用set或unordered_set,因为数据不是键值对的形式.

现在set插入比unordered_set插入更昂贵,但数据结构只在我的程序开头填充一次.

我相信决定因素是我可以多快地迭代数据结构的所有元素.我不确定set或unordered_set对于此目的是否会更快.我相信标准没有提到这个事实,因为这个操作对于任一数据结构都是O(n).但我想知道iterator.next()哪个数据结构会更快.

c++ stl set unordered-set c++11

15
推荐指数
2
解决办法
1万
查看次数