考虑以下
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*因为它不是变量的地址Run Code Online (Sandbox Code Playgroud)foo<&dum_ref>();
编辑:
自从C++ 17,std::addressof被标记为constexpr,所以我猜它应该工作.
我有一个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++ 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函数中的转发引用传递?
我正在存储包含表情符号的数据,数据以 json 形式出现,所以当我检索它时,它就像
\n\n\n\n\n“吉格斯\'ern har v\xc3\xa6rt \xc3\xa5 koset seg igjen(方括号)Dette er en fillesak”
\n
当我将其存储到 MySQL 中时,出现以下错误:
\n\n\n\n\n2016-05-0213:12:45.582 [错误] pool-1-thread-1 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - 字符串\n 值不正确:
\n\'\\xF0\\x9F\\x98\\x8A\\x0A<...\'对于\'comment\'第 1 行的列
我已将\nMySQL 数据库编码更改为utf8mb4但没有解决问题。
在考虑问题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.
我没有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使用指针在其他地方/其他地方生成.
我做了一些测试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?
作为条件运算符()的结果,我正在使用左值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)在编译时就已知(例如通过定义它 …
有一种模板函数可以通过引用+回调函数传递一个参数,但如果通过引用回调函数传递参数然后编译器抛出错误就会出现问题:
没有匹配的呼叫功能
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) 正如在这个问题中看到的那样,OP试图让以下语句迭代数字.
for (int n : 10)
cout << n << endl;
Run Code Online (Sandbox Code Playgroud)
显然,语法错误,因为int没有begin()和end()方法.但它应该是可能的.基于基于范围的for循环的文档,这很重要.
for(range_declaration:range_expression)loop_statementrange_expression - 表示合适序列的任何表达式(定义了开始和结束成员函数或自由函数的数组或对象,请参阅下文)或braced-init-list.
和以下
上述语法产生码等效于以下(
__range,__begin并且__end是为了说明仅):Run Code Online (Sandbox Code Playgroud){ // until C++17 auto && __range = range_expression ; for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }
澄清begin_expr和end_expr是:
begin_expr和end_expr定义如下:
- 如果range_expression …