上周,埃里克Niebler 啾啾了一个非常紧凑的实现std::is_functiontraits类:
#include <type_traits>
template<int I> struct priority_tag : priority_tag<I - 1> {};
template<> struct priority_tag<0> {};
// Function types here:
template<typename T>
char(&is_function_impl_(priority_tag<0>))[1];
// Array types here:
template<typename T, typename = decltype((*(T*)0)[0])>
char(&is_function_impl_(priority_tag<1>))[2];
// Anything that can be returned from a function here (including
// void and reference types):
template<typename T, typename = T(*)()>
char(&is_function_impl_(priority_tag<2>))[3];
// Classes and unions (including abstract types) here:
template<typename T, typename = int T::*>
char(&is_function_impl_(priority_tag<3>))[4];
template <typename T>
struct is_function
: …Run Code Online (Sandbox Code Playgroud) 如何在C中获取进程名称?同名,在/proc/$pid/status.我不想解析该文件.有没有任何程序化的方法来做到这一点?
C++ 允许动态分配零大小的数组:
int* p = new int[0];
delete[] p;
Run Code Online (Sandbox Code Playgroud)
我不能用这样的指针做很多事情(因为数组没有元素),但是新表达式需要给我一个有效的(!= nullptr)指针,然后我必须delete[]再次将它作为一个实际的数组.
有关这种新表达式返回的内存对齐的要求吗?考虑:
struct alignas(8) Foo {
int x;
};
Foo* p = new Foo[0];
delete[] p;
Run Code Online (Sandbox Code Playgroud)
为p保证指向8对齐的地址?此外,如果我编写自定义分配器,在这种情况下我是否需要返回指向对齐地址的指针?
我有一堆代码,std::string比较类型的对象与字符串文字的相等性.像这样的东西:
//const std:string someString = //blahblahblah;
if( someString == "(" ) {
//do something
} else if( someString == ")" ) {
//do something else
} else if// this chain can be very long
Run Code Online (Sandbox Code Playgroud)
比较时间累积到一个严重的数量(是的,我描述),所以加快它是很好的.
代码将字符串与众多短字符串文字进行比较,这种比较很难避免.保留声明的字符串std::string很可能是不可避免的 - 有数千行代码.离开字符串文字和比较==也可能是不可避免的 - 重写整个代码将是一个痛苦.
问题是Visual C++ 11附带的STL实现使用了一些奇怪的方法.==映射到std::operator==(const basic_string&, const char*)哪些调用basic_string::compare( const char* ),这些调用又调用std::char_traits<char>( const char* )哪些调用strlen()来计算字符串文字的长度.然后对两个字符串运行比较,并将两个字符串的长度传递给该比较.
编译器很难分析所有这些并发出遍历字符串文字两次的代码.使用短文字,时间不多,但每次比较都涉及遍历文字两次而不是一次.简单地打电话strcmp()很可能会更快.
有没有什么我可以做的,比如编写一个自定义比较器类,有助于避免在这种情况下两次遍历字符串文字?
以下是make CMakeLists.txt的片段:
add_library(foo-object OBJECT src/foo.cpp)
target_include_directories(foo-object PUBLIC include)
add_library(foo SHARED $<TARGET_OBJECTS:${PROJECT_NAME}-object>)
add_library(foo_static STATIC $<TARGET_OBJECTS:${PROJECT_NAME}-object>)
Run Code Online (Sandbox Code Playgroud)
现在,这一切都很好,两个库都生成了.但是当我尝试使用它时遇到问题:
add_executable(bar src/main.cpp)
target_link_libraries(bar foo)
Run Code Online (Sandbox Code Playgroud)
Target bar不编译,因为不传播来自foo-object的include目录.如果我也target_include_directories直接添加foo,一切都会正常编译.
我如何制作foo并foo_static自动使用(并根据它们转发内容)包含目录foo-object?
我无法从C++ 11标准中看出nullptr_t是否有默认构造函数.换句话说,以下是否有效?:
nullptr_t n;
Run Code Online (Sandbox Code Playgroud)
GCC和VC++允许上面的代码,但clang没有.我在标准中找不到任何指定它没有默认构造函数的东西,我能找到它表明它应该.这对我很重要,因为我正在为较旧的编译器支持编写nullptr的基本回退实现,并且需要知道是否需要为其提供默认构造函数.
我在弄清楚确切的语义时遇到了一些麻烦std::string.length().该文件明确指出,length()返回字符的字符串中而且数量不是字节数.我想知道在哪些情况下这实际上有所作为.
特别是,这只与非char实例化相关,std::basic_string<>或者在存储具有多字节字符的UTF-8字符串时是否也会遇到麻烦?标准是否允许length()UTF8感知?
我正在寻找一些很好的实际例子,说明ABA问题导致多线程代码出现问题.
执行原子比较和交换指令时,并发代码中会出现ABA问题.如果线程在执行比较和交换之前立即中断,则第二个线程可能会更改比较和交换的目标从其初始值A更改为不同的值B.如果它然后将值更改回A在第一个线程恢复之前,尽管目标值发生了变化,但compare-and-swap仍会成功.
在许多情况下,ABA不是问题.以共享引用计数为例:即使refcount同时更改,我们也没有问题,只要我们永远不会从已经下降到0的refcount增加.所以我们显然只对目标是否匹配感兴趣交换时的预期价值,而不是过去的变化.
在维基百科页面具有从ABA遭受无锁栈实现的例子,但我个人没有碰上在生产代码的问题为止.我只是好奇是否有人有一些很好的战争故事来分享ABA.
std::is_constructible具有私有或受保护的析构函数的类型的预期结果是什么?
例如,我仍然可以在堆上构造这样的对象,即使只有朋友可以释放它:
#include <type_traits>
class Foo
{
friend void freeFoo(Foo*);
public:
Foo()
{}
private:
// Destructor is private!
~Foo()
{}
};
void freeFoo(Foo* f)
{
delete f; // deleting a foo is fine here because of friendship
}
int main()
{
Foo* f = new Foo();
// delete f; // won't compile: ~Foo is private
freeFoo(f); // fine because of friendship
if(!std::is_constructible<Foo>::value)
{
std::cout << "is_constructible failed" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
is_constructible对gcc和Visual C++(coliru上的gcc演示)进行最终检查都会失败.
这是标准所要求的行为吗?如果是这样,有没有办法检查类型是否具有特定的构造函数,无论析构函数上的访问说明符是什么?
如何配置 CMake 以将编译器警告视为构建期间的错误?
我知道可以-Werror通过诸如 之类的命令手动配置编译器的命令行选项target_compile_options,但我更喜欢不需要摆弄依赖于工具的选项的便携式解决方案。
c++ ×7
c++11 ×3
cmake ×2
string ×2
type-traits ×2
allocator ×1
atomic ×1
c ×1
c++14 ×1
clang ×1
concurrency ×1
gcc ×1
linux ×1
nullptr ×1
performance ×1
stdstring ×1
stl ×1
templates ×1
visual-c++ ×1