小编Zer*_*ges的帖子

是全局变量constexpr的地址吗?

考虑以下

struct dummy{};

dummy d1;
dummy d2;

template<dummy* dum>
void foo()
{
    if (dum == &d1)
        ; // do something
    else if (dum == &d2)
        ; // do something else
}
Run Code Online (Sandbox Code Playgroud)

现在,可以foo像这样打电话

foo<&d1>();
foo<&d2>();
Run Code Online (Sandbox Code Playgroud)

一切都按预期工作.但是以下没有

constexpr dummy* dum_ptr = &d1;
foo<dum_ptr>();
Run Code Online (Sandbox Code Playgroud)

来自Visual Studio的这个错误

错误C2975 :: dum_ptr无效的模板参数foo,预期的编译时常量表达式

虽然这有效

constexpr dummy& dum_ref = d1;
foo<&dum_ptr>();
Run Code Online (Sandbox Code Playgroud)

在visual studio中,但不是在G ++中,因为

注意:模板参数推断/替换失败:
错误:& dum_ref不是有效的模板参数,dummy*因为它不是变量的地址

foo<&dum_ref>();
Run Code Online (Sandbox Code Playgroud)

编辑:
自从C++ 17,std::addressof被标记为constexpr,所以我猜它应该工作.

language-lawyer c++11

14
推荐指数
1
解决办法
869
查看次数

通过数据重对象的元组索引无序映射

我有一个std::unordered_map<std::tuple<A, A>, B> map;.我有一个修改这样的地图的功能

void modify(const A& a1, const A& a2)
{
    map[/* a1, a2 */].modify();
}
Run Code Online (Sandbox Code Playgroud)

现在我有点担心不必要的副本A.这是我的尝试.

map[{a1, a2}].modify();
Run Code Online (Sandbox Code Playgroud)

看起来干净,但它构建了从副本临时密钥(元组)a1,a2.

map[std::tie(a1, a2)].modify();
Run Code Online (Sandbox Code Playgroud)

这看起来很有希望,因为它构造std::tuple<const A&, const A&>并将其传递给map operator[].operator[]我的地图签名是

B& operator[](const std::tuple<A, A>&)
B& operator[](std::tuple<A, A>&&)
Run Code Online (Sandbox Code Playgroud)

哪个与返回类型不匹配std::tie,但它有效.所以我看一下构造函数,std::tuple并发现转换构造函数,这让我想到,复制品仍在制作中(所以我测试了它).

有没有办法查询地图,没有任何不必要的副本,仍然保持O(1)平均查找复杂性?

c++ c++11

10
推荐指数
1
解决办法
183
查看次数

为什么模板化仿函数作为值传递而不是转发参考

在讨论中,我在这里玩弄着传球手.C++ STL传递函子作为值(见于std::for_each,std::find_if,std::transform)

所以宣布我的就是这样的.

template<typename F>
void call_me(F f)
{
    f();
}
Run Code Online (Sandbox Code Playgroud)

现在,调用call_me(ftor{})可能会调用ftor复制构造函数(它很可能是复制省略,所以不是这样).但ftor f{}; call_me(f);会导致复制.如果ftor有大量数据,则可能是个问题.

我们通过将它作为const引用(void call_me(const F& f))传递来去除不需要的副本来改进它.只要ftor::operator()是这样就可以了const.如果不是,则调用call_me将导致编译错误(丢失const限定符).

那么,为什么要使用const引用,只需使用reference(void call_me(F& f)).这很好,但它不适用于第一种情况,call_me(ftor{})因为将r值转换为(非常量)l值引用无效.

声明f为转发引用(void call_me(F&& f))似乎适用于所有情况.我相信,这可以归功于参考折叠.

那么,为什么模板化仿函数不作为STL函数中的转发引用传递?

c++ templates c++11

9
推荐指数
1
解决办法
519
查看次数

在 MySQL 中存储表情符号出现错误的字符串值错误

我正在存储包含表情符号的数据,数据以 json 形式出现,所以当我检索它时,它就像

\n\n
\n

“吉格斯\'ern har v\xc3\xa6rt \xc3\xa5 koset seg igjen(方括号)Dette er en fillesak”

\n
\n\n

当我将其存储到 MySQL 中时,出现以下错误:

\n\n
\n

2016-05-0213:12:45.582 [错误] pool-1-thread-1 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - 字符串\n 值不正确:\'\\xF0\\x9F\\x98\\x8A\\x0A<...\'对于\'comment\'第 1 行的列

\n
\n\n

我已将\nMySQL 数据库编码更改为utf8mb4但没有解决问题。

\n

java mysql json

8
推荐指数
2
解决办法
7471
查看次数

通过枚举值构造initializer_list包含随机值

在考虑问题std :: initializer list的解决方案时,从现有的std :: array而不枚举每个元素,我开发了类似bolov做的机制,但没有构造对象,而只是初始化列表.我很惊讶我的解决方案不起作用,我无法弄清楚原因.

#include <initializer_list>
#include <iostream>
#include <array>

template<typename T, std::size_t N, std::size_t... Is>
std::initializer_list<T> array_to_init_list_helper(std::array<T, N> arr, std::index_sequence<Is...>)
{
    return {arr[Is]...};
}

template<typename T, std::size_t N>
std::initializer_list<T> array_to_init_list(std::array<T, N> arr)
{
    return array_to_init_list_helper(arr, std::make_index_sequence<N>{});
}

int main()
{
    std::array<int, 5> arr{1, 2, 3, 4, 5};
    auto init_list = array_to_init_list(arr);
    for (auto val : init_list)
        std::cout << val << " ";
}
Run Code Online (Sandbox Code Playgroud)

得到随机值,而我希望得到的值arr.

c++ initializer-list c++11

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

在QThread中调用QThread.exec()方法是必要的吗?

我没有exec()在我的代码中调用,但是timer并且QUdpSocket工作正常.被exec()用于等待的event继续吗?

更新:timer工作正常,因为我没有打电话moveToThread(this)QThread,这意味着它QThread实际上仍然是其中的一部分main thread.至于QUdpSocket我使用投票functions.所以它不需要合作signals.

提示:如果你需要做init一些东西,那需要event loop你的QThread,你可以delay打电话,moveToThread直到你不再需要它signals,这在程序加载时是实用的.您也不需要在构造函数中调用它run()(例如,您可以在内部调用它),只需将this QThread指针复制到变量并call使用指针在其他地方/其他地方生成.

qt multithreading qthread

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

C++无法将lambda转换为std :: pair中的std :: packaged_task

我做了一些测试std::packaged_task并遇到了这个问题.

std::packaged_task<int(void)> task([]() -> int { return 1; });
task();
Run Code Online (Sandbox Code Playgroud)

编译并调用task()lambda.但是,这不编译:

std::pair<int, std::packaged_task<int(void)>> pair(15, []() -> int { return 15; });
pair.second();
Run Code Online (Sandbox Code Playgroud)

因为

错误C2664:' std::pair<int,std::packaged_task<int (void)>>::pair(const std::pair<int,std::packaged_task<int (void)>> &)':无法将参数2从' main::<lambda_abbe6cccb9110894d95e872872ec1296>' 转换为' const std::packaged_task<int (void)> &'

但是,这会编译:

std::vector<std::packaged_task<int()>> v;
v.emplace_back([](){ return 1; })
Run Code Online (Sandbox Code Playgroud)

为什么我不能创建一个pair

c++ lambda stl c++11

5
推荐指数
1
解决办法
903
查看次数

条件运算符的引用语义

作为条件运算符()的结果,我正在使用左值cond ? expr1 : expr2.

考虑以下示例

class /*(1)*/ Value {
    public int MagicNumber { get; private set; } = 0;
    public void Increment() {
        /* magical code, that modifies MagicNumber */
    }
}

void Main()
{
    Value v1, v2;
    /*(2)*/ bool condition = /*...*/;
    (condition ? v1 : v2).Increment(); // (3)
}
Run Code Online (Sandbox Code Playgroud)

现在,我会怀疑,基于价值condition,要么v1还是v2被递增.实际上就是这种情况,只要Value((1))是类.一旦我将其更改为struct,它就变成了值类型而行(3)没有做任何事情(我怀疑是因为其中一个v1或被v2复制,递增和丢弃).到此为止,这是有道理的.奇怪的行为开始一次(2)(condition)在编译时就已知(例如通过定义它 …

c#

5
推荐指数
1
解决办法
117
查看次数

C++ 11:函数模板:通过引用传递参数

有一种模板函数可以通过引用+回调函数传递一个参数,但如果通过引用回调函数传递参数然后编译器抛出错误就会出现问题:

没有匹配的呼叫功能func(int&, void (&)(int&)).

怎么了?

template<typename T> 
using func_t = void(T);

template<typename T>
void func(T& arg, func_t<T> callback) {
    callback(arg);
} 

void func1(int arg) {  }
void func2(int& arg) { } //<-- (1)

int main() {
    int x = 0;
    func(x, func1);
    func(x, func2); //<-- (2) compilation error 
}
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

4
推荐指数
1
解决办法
146
查看次数

范围基于用于原始类型

正如在这个问题中看到的那样,OP试图让以下语句迭代数字.

for (int n : 10)
    cout << n << endl;
Run Code Online (Sandbox Code Playgroud)

显然,语法错误,因为int没有begin()end()方法.但它应该是可能的.基于基于范围的for循环的文档,这很重要.

for ( range_declaration : range_expression ) loop_statement

range_expression - 表示合适序列的任何表达式(定义了开始和结束成员函数或自由函数的数组或对象,请参阅下文)或braced-init-list.

和以下

上述语法产生码等效于以下(__range,__begin并且__end是为了说明仅):

{ // until C++17
    auto && __range = range_expression ;
    for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
        range_declaration = *__begin;
        loop_statement
    }
}
Run Code Online (Sandbox Code Playgroud)

澄清begin_exprend_expr是:

begin_exprend_expr定义如下:

  • 如果range_expression …

c++ language-lawyer c++14

3
推荐指数
1
解决办法
78
查看次数