这编译:
int main() {
const int x = 123;
auto g = []() { std::cout << x << "\n"; };
g();
}
Run Code Online (Sandbox Code Playgroud)
但是这个:
int main(){
const float x = 123;
auto g = []() { std::cout << x << "\n"; };
g();
}
Run Code Online (Sandbox Code Playgroud)
生产:
"错误:'x'未被捕获"
为什么?
我已经在GCC(各种版本从5.0.0到8.0.0)和Clang(各种版本从4.0.0到6.0.0)上测试过它.它在所有情况下都表现相同.
我在使用GCC编译以下程序时遇到问题(我尝试了很多版本,都失败并出现相同的错误).它在Clang编译得很好:
#include <vector>
struct Tag1
{
static void logAllocation(){}
static void logDeallocation(){}
};
struct Tag2
{
static void logAllocation(){}
static void logDeallocation(){}
};
template<typename Tag, typename T>
struct MyAllocator
{
using value_type = typename std::allocator<T>::value_type;
T* allocate(std::size_t n)
{
Tag::logAllocation();
return std::allocator<T>{}.allocate(n);
}
void deallocate(T* p, std::size_t n)
{
Tag::logDeallocation();
std::allocator<T>{}.deallocate(p, n);
}
};
int main()
{
std::vector<int, MyAllocator<Tag1, int>> vec;
}
Run Code Online (Sandbox Code Playgroud)
问题是GCC认为在Tag==int
内部MyAllocator
,我得到一个错误,'logDeallocation'不是'int'的成员.这是GCC中的错误吗?当我翻转模板参数(template<typename T, typename Tag
)并std::vector<int, MyAllocator<int, Tag1>> vec;
在编译时声明我的矢量.
假设我想使用带有unique_ptr的自定义删除器:
void custom_deleter(int* obj)
{
delete obj;
}
Run Code Online (Sandbox Code Playgroud)
为什么我要写这个:
std::unique_ptr<int, void(*)(int*)> x(new int, custom_deleter);
Run Code Online (Sandbox Code Playgroud)
而不是这个:
std::unique_ptr<int> x(new int, custom_deleter); //does not compile
Run Code Online (Sandbox Code Playgroud)
?
不能推断出删除器的类型吗?
考虑一下这段代码:
template<typename FirstArg>
void foo()
{
}
template<typename FirstArg, typename... RestOfArgs>
void foo()
{
foo<RestOfArgs...>();
}
int main()
{
foo<int, int, int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
foo<RestOfArgs...>();
当RestOfArgs
只有一个元素({int}
)时,它不会因为模糊调用而编译.
但这编译没有错误:
template<typename FirstArg>
void foo(FirstArg x)
{
}
template<typename FirstArg, typename... RestOfArgs>
void foo(FirstArg x, RestOfArgs... y)
{
foo(y...);
}
int main()
{
foo<int, int, int>(5, 6, 7);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么第一种情况存在歧义?
为什么第二种情况没有歧义?
以下代码在Clang中编译,但在GCC中不编译:
template<typename T>
struct Widget
{
template<typename U>
void foo(U)
{
}
template<>
void foo(int*)
{
}
};
Run Code Online (Sandbox Code Playgroud)
根据C++标准([temp.expl.spec],第2段):
可以在可以定义相应主模板的任何范围中声明显式特化
这是GCC中的一个错误,如果是这样,我怎样才能在它的bug追踪器中找到它?
这是GCC的输出:
prog.cc:13:14: error: explicit specialization in non-namespace scope 'struct Widget<T>'
template<>
^
Run Code Online (Sandbox Code Playgroud)
我正在使用GCC HEAD 8.0.1 -std=c++2a
.
我很难理解先发制人的一件事.引用维基百科:
在计算中,抢占(更正确地抢占)是暂时中断由计算机系统执行的任务的行为,而不需要其合作,并且意图在稍后的时间恢复任务.这种变化称为上下文切换.它通常由特权任务或称为抢占式调度程序的系统的一部分执行,该系统具有抢占,中断和稍后恢复系统中其他任务的能力.
所以,基本上,他们说调度程序可以中断当前正在运行的任务.这怎么可能呢?CPU正在运行此任务的代码,而不是调度程序的代码.那么调度程序如何做任何事情呢?
我的猜测是必须有某种硬件定时器,在经过一段时间后会物理地中断CPU并将控制权交还给调度程序.它是否正确?有没有我可以更详细地阅读的文件?
任何答案都将受到高度赞赏.
由于std::set
不能包含重复元素且始终排序,因此std::set::equal_range
将始终返回包含none或1元素的范围.从技术上讲,是的,这仍然是一个范围,但这个算法的目的是什么?因为std::set
它似乎没必要.
是否std::function
支持完美的论证转发?我决定测试一下:
struct Widget
{
void operator()(int const&)
{
std::cout << "lvalue";
}
void operator()(int&&)
{
std::cout << "rvalue";
}
};
std::function<void(int)> f{Widget()};
int x = 5;
f(x);
Run Code Online (Sandbox Code Playgroud)
猜猜哪个operator()
被调用 - 采用右值参考的那个.它似乎是设计的.这种行为背后的理由是什么?
如果从一个模板类派生,必须限定基类成员的用法有两种Base::
或this->
.这是可以理解的,因为基类的成员是依赖于模板的名称.但是还有第三种选择 - 你可以使用using
声明.我决定尝试一下,但有一些更复杂的层次结构:
struct Gadget
{
void gadge()
{
}
};
struct Base1
{
Gadget g;
};
template<typename T>
struct Base2 : Base1
{
};
template<typename T>
struct Widget : Base2<T>
{
using Base1::g;
void foo()
{
g.gadge();
}
};
Run Code Online (Sandbox Code Playgroud)
但问题是g.gadge
不会在某些编译器上编译.特别是,GCC 5.5.0和GCC HEAD(8.0.1)将发出以下错误消息:
prog.cc: In member function 'void Widget<T>::foo()':
prog.cc:27:11: error: 'struct Base1' has no member named 'gadge'
g.gadge();
^~~~~
Run Code Online (Sandbox Code Playgroud)
另一方面,它使用GCC 6.1.0,GCC 7.2.0以及我尝试过的所有Clang版本进行编译和工作.哪个编译器是对的?
我一直在与飞船操作员一起玩,我想知道以下行为的原因是什么:
struct ArrayWrapper
{
int arr[3];
auto operator<=>(const ArrayWrapper&) const = default;
};
ArrayWrapper a1{1,2,3}, a2{1,2,4};
auto x = a1 <=> a2; // this compiles and works, x is std::strong_ordering::less
Run Code Online (Sandbox Code Playgroud)
数组比较适用于成员数组。它也适用于std::array
:
std::array<int, 3> arr1{1,2,4};
std::array<int, 3> arr2{1,2,3};
auto x = arr1 <=> arr2; // x is std::strong_ordering::greater
Run Code Online (Sandbox Code Playgroud)
但是,它不适用于非成员的原始数组:
int rawArr1[3]{1,2,3}, rawArr2[3]{1,2,3};
auto x = rawArr1 <=> rawArr2; // error: invalid operands of types ‘int [3]’ and ‘int [3]’ to binary ‘operator<=>’
Run Code Online (Sandbox Code Playgroud)
我已经在 GCC 11 上测试过了,原因是什么?考虑到它适用于数组成员,这似乎很奇怪。
c++ ×9
templates ×3
gcc ×2
arrays ×1
c++11 ×1
c++20 ×1
inheritance ×1
lambda ×1
preemption ×1
scope ×1
stl ×1
unique-ptr ×1
x86 ×1