小编Vit*_*meo的帖子

通用lambda及其参数作为常量表达式

以下代码被GCC 7.2和clang 5.0.0接受,但被Microsoft VS 2017 15.5.0 Preview 5和Intel C++编译器19拒绝:

struct S { };

constexpr int f(S)
{
    return 0;
}

int main()
{
    auto lambda = [](auto x)
    {
        constexpr int e = f(x);
    };

    lambda(S{});
}
Run Code Online (Sandbox Code Playgroud)

微软:

<source>(12): error C2131: expression did not evaluate to a constant
Run Code Online (Sandbox Code Playgroud)

英特尔:

<source>(12): error: expression must have a constant value
    constexpr int e = f(x);
                      ^
<source>(12): note: the value of parameter "x" (declared at line 10) cannot be used as a constant …
Run Code Online (Sandbox Code Playgroud)

c++ lambda language-lawyer c++14

7
推荐指数
1
解决办法
389
查看次数

将条件作为参数传递

是否可以将条件作为参数传递给操作?

这是一个例子.

public void Test(Action action, Condition condition);
Run Code Online (Sandbox Code Playgroud)

...

Test( () => Environment.Exit(0), () => variable == variable2 );
Run Code Online (Sandbox Code Playgroud)

.net c# conditional boolean

6
推荐指数
1
解决办法
6324
查看次数

std :: unordered_set是连续的(比如std :: vector)吗?

我在std :: unordered_set中存储指针,因为我不想要任何重复(我删除了集合中的指针,所以如果有重复,我会尝试删除已经删除的指针).我在这些集合中循环很多,因为我知道std :: vector是最快的循环容器(连续内存),我想知道std :: unordered_set是否也是这样做的.

如果没有,会使用std :: vector并检查指针是否被删除更快?

c++ performance vector unordered-set c++11

6
推荐指数
1
解决办法
3375
查看次数

“gnu-zero-variadic-macro-arguments”可以安全地忽略吗?

考虑以下代码(实例)

#define TEST_VA(mX, ...) TEST
#define STRINGIFY_IMPL(mX) #mX
#define STRINGIFY(mX) STRINGIFY_IMPL(mX)

#include <iostream>

int main()
{
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
    std::cout << STRINGIFY(TEST_VA()) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang++ 3.4抱怨:

main.cpp:9:37: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
                                    ^
main.cpp:1:9: note: macro 'TEST_VA' defined here
#define TEST_VA(mX, ...) TEST
        ^
main.cpp:10:33: warning: must specify at least one argument for '...' parameter of variadic macro …
Run Code Online (Sandbox Code Playgroud)

c++ warnings c-preprocessor variadic-macros c++11

6
推荐指数
1
解决办法
5885
查看次数

预处理器计数器宏

有没有办法创建一个COUNTER()宏(遵循C++ 11/14标准),它被扩展为每次COUNTER()调用时增加1的数字?

我已经考虑过了,但却找不到让它发挥作用的方法.我没有找到在COUNTER()宏中存储"状态"的方法.

例:

#define COUNTER() <...> // Implementation goes here...
#define UNIQUE_NAME_1() TEST ## COUNTER()
#define UNIQUE_NAME_2() TEST ## COUNTER()

// Note how the COUNTER() macro can be used with other macros
// (it cannot be implemented with C++ code)

int main() {
    std::cout << STRINGIFY(UNIQUE_NAME_1()) << std::endl;
    std::cout << STRINGIFY(UNIQUE_NAME_2()) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

预期产量:

TEST0 
TEST1    
Run Code Online (Sandbox Code Playgroud)

c++ macros counter c-preprocessor

6
推荐指数
1
解决办法
3238
查看次数

删除右值,保持左值引用(标准类型特征可用吗?)

我正在尝试编写一个函数,该函数以一个形式返回一个可变参数包的子集std::tuple.理想情况下,该函数不应具有运行时开销(没有不必要的副本),并且应该允许用户访问lvalue引用并修改它们.

应保持值类型,lvalue引用和const lvalue引用.Temporaries(rvalue引用)应该"转换"为值类型,以避免创建无效引用(对临时引用的引用).

期望结果的示例:

int lr = 5;
const int& clr = lr;

auto t = make_subpack_tuple(lr, clr, 5);

static_assert(is_same
<
    decltype(t), 
    std::tuple<int&, const int&, int>
>{}, "");

// Ok, modifies lr:
std::get<0>(t) = 10;

// Compile-time error, intended:
// std::get<1>(t) = 20;

// Ok, 5 was moved into the tuple:
std::get<2>(t) = 30;
Run Code Online (Sandbox Code Playgroud)

示例不完整实施:

template<typename... Ts>
auto make_subpack_tuple(Ts&&... xs)
{
    return std::tuple
    <
        some_type_trait<decltype(xs)>...
    >
    (
        std::forward<decltype(xs)>(xs)...
    );
} …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits rvalue-reference perfect-forwarding c++14

6
推荐指数
1
解决办法
489
查看次数

组合std :: forward,std :: move和volatile时出现意外的返回类型

上gcc.godbolt.org.

我创建了一个简单的类型特征来删除右值引用:

template <typename T>
struct remove_rvalue_reference { using type = T; };

template <typename T>
struct remove_rvalue_reference<T&&> { using type = T; };

template <typename T>
using remove_rvalue_reference_t = 
    typename remove_rvalue_reference<T>::type;
Run Code Online (Sandbox Code Playgroud)

我用它来实现一个copy_if_rvalue(x)函数,其返回类型取决于传递的参数:

template <typename T>
constexpr auto copy_if_rvalue(T && x) 
  -> remove_rvalue_reference_t<decltype(std::forward<decltype(x)>(x))>
{
    return std::forward<decltype(x)>(x);
}
Run Code Online (Sandbox Code Playgroud)

为了确保函数返回正确的类型,我编写了一些简单的静态断言:

// literal
static_assert(std::is_same<
    decltype(copy_if_rvalue(0)), int
>{});

// lvalue
int lv = 10;
static_assert(std::is_same<
    decltype(copy_if_rvalue(lv)), int&
>{});

// const lvalue
const int clv = 10;
static_assert(std::is_same<
    decltype(copy_if_rvalue(clv)), const int& …
Run Code Online (Sandbox Code Playgroud)

c++ decltype language-lawyer trailing-return-type c++14

6
推荐指数
1
解决办法
116
查看次数

捕获和调试无效使用对移动的lambda内部的局部变量的引用

我在我的一个真实项目中遇到了一个难以调试的情况,我不小心访问了已被移动的lambda中的局部变量的引用.访问是从另一个线程完成的,但移动的lambda保持活着直到第二个线程完成.

该错误仅在禁用优化时发生,并且是由粗心重构引起的.

我创建了一个最小的例子(可在wandbox上找到),它可以重现这个问题:

struct state
{
    int x = 100;
};

template <typename TF>
void eat1(TF&& f)
{
    // Call the lambda.
    f();

    // Simulate waiting for the second thread
    // to finish.
    std::this_thread::sleep_for(1000ms);
}

template <typename TF>
void eat0(TF&& f)
{
    // Move the lambda to some other handler.
    eat1(std::forward<TF>(f));
}

void use_state(state& s)
{
    // Will print `100`.
    std::cout << s.x << "\n";

    // Separate thread. Note that `s` is captured by
    // reference. …
Run Code Online (Sandbox Code Playgroud)

c++ debugging sanitizer undefined-behavior c++14

6
推荐指数
1
解决办法
142
查看次数

使用方法失败更改constexpr对象成员

我试图constexpr通过方法更改对象成员的值但我不明白为什么它不适用于这种特定情况:

#include <iostream>

struct test
{
    int m_counter = 0;

    constexpr test()
    {
        m_counter++;
        m_counter++;
        increment();
        increment();
        increment();
    }

    constexpr void increment()
    {
        m_counter++;   
    }

    constexpr int value() const
    {
        return m_counter;
    }
};

template<int value>
constexpr void check()
{
    std::cout << value << std::endl;
}

// constexpr test t; // value = 3, why ?

int main()
{
    constexpr test t; // value = 5, ok
    check<t.value()>();
}
Run Code Online (Sandbox Code Playgroud)

当我在全局范围内创建对象时,我不明白为什么值为3.msvc和clang在两种情况下都显示5但不是gcc.谁错了?

c++ gcc object constexpr c++14

6
推荐指数
1
解决办法
270
查看次数

从可变参数值初始化中推导出类模板参数(clang vs g ++)

考虑以下可变参数类模板:

template <typename... Ts>
struct foo
{
    template <typename... Us>
    foo(Us...) { }
};
Run Code Online (Sandbox Code Playgroud)

如果我尝试以foo下列方式实例化,g ++(trunk)和clang ++(trunk)都很高兴:

auto o = foo{};
Run Code Online (Sandbox Code Playgroud)

在godbolt.org上


一旦我用括号切换到值初始化,g ++就无法编译(而clang ++仍然很开心):

auto o = foo();
Run Code Online (Sandbox Code Playgroud)
error: cannot deduce template arguments for 'foo' from ()
     auto o = foo();
                  ^
Run Code Online (Sandbox Code Playgroud)

在godbolt.org上


这是一个g ++错误,还是在初始化和初始化之间处理类模板参数推导的方式有什么不同?{}()


这也适用于适当的演绎指南:https: //godbolt.org/g/qReXpM.

c++ language-lawyer variadic-templates template-argument-deduction c++17

6
推荐指数
0
解决办法
131
查看次数