小编Sla*_*ica的帖子

从积分常量表达式转换为空指针

考虑以下代码:

#include <memory>

void f( std::shared_ptr<int> ) {}

int main()
{
    f( 0 );               // compiles fine in gcc and clang
    f( 1 - 1 );           // compiles fine in gcc, fails in clang
    constexpr int i = 0;
    f( i );               // fails to compile in gcc and clang
    f( i - 0 );           // compiles fine in gcc, fails in clang
}
Run Code Online (Sandbox Code Playgroud)

为什么只能f( i )编译,但i应该被评估为值0的编译时常量?

用g ++ v 5.1.0检查PS,它接受所有变体,除了f(i);c ++ 11和c ++ …

c++ null gcc c++11 c++14

14
推荐指数
2
解决办法
732
查看次数

std :: map范围擦除复杂性

cppreference.com说范围擦除的复杂性std::map是:

log(c.size())+ std :: distance(first,last)

而迭代器对单个元素的擦除是分摊的常量.所以,如果我在循环中擦除元素:

for( auto it = first; it != last; it = map.erase( it ) );
Run Code Online (Sandbox Code Playgroud)

这应该是线性的std::distance(first, last),cplusplus.com同意这一点.标准说什么?这是cppreference.com上的错字吗?

c++ stdmap time-complexity

9
推荐指数
2
解决办法
2305
查看次数

为什么内置类型的链接前缀增量/减量不是C++的UB?

在cpprefernce.com 前缀增量的示例中,有这样的代码:

int n1 = 1;
...
int n3 = ++ ++n1;
Run Code Online (Sandbox Code Playgroud)

为什么在这种情况下链式增量不会导致UB?在这种情况下,最多一次修改的规则是否违反?

c++ prefix-operator

8
推荐指数
1
解决办法
222
查看次数

C++中链调用的评估顺序

假设我们上课了A:

class A {
public:
    A& func1( int ) { return *this; }
    A& func2( int ) { return *this; }
};
Run Code Online (Sandbox Code Playgroud)

和2个立场功能:

int func3();
int func4();
Run Code Online (Sandbox Code Playgroud)

现在在这段代码中:

A a;
a.func1( func3() ).func2( func4() );
Run Code Online (Sandbox Code Playgroud)

是功能评估的顺序func3()func4()定义?

根据这个答案未定义的行为和序列点之一的序列点是:

  • 在函数体(§1.9/17)中执行任何表达式或语句之前发生的所有函数参数(如果有)的评估之后,在函数调用(函数是否为内联函数)之后.

那么"所有函数参数的评估"是什么意思,func3()必须先调用,func4()因为func1()参数的评估必须在调用之前发生func2()

c++ operator-precedence

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

透明比较器代码最小化

假设我们存储一个带有字符串键的结构,我们希望通过容器中的字符串找到它std::set,所以常见的实现看起来像这样:

struct Foo {
    std::string id;
};

struct FooComp {
    using is_transparent = std::true_type;

    bool operator()( const Foo &foo, const std::string &str ) const
    {
        return foo.id < str;
    }

    bool operator()( const std::string &str, const Foo &foo ) const
    {
        return str < foo.id;
    }

    bool operator()( const Foo &foo1, const Foo &foo2 ) const
    {
        return foo1.id < foo2.id;
    }
};

 std::set<Foo,FooComp> foo_set;
 ...
Run Code Online (Sandbox Code Playgroud)

这样可以正常工作,但是编写三种方法的FooCompprety匹配相同(逻辑上)是单调的,容易出错.有没有办法最小化该代码?

c++ c++14

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

C++为中间件生成类型提供`operator <<`的通用方法

我们使用中间件为我们生成各种编程语言类型,包括C++.对于为C++生成的结构,我想注入可用于各种数据转换的代码,例如输出到std::ostream.假设我们生成了以下结构:

struct Foo {
    int a;
    double d;
};
Run Code Online (Sandbox Code Playgroud)

假设我改变了中间件编译器来生成以下模板函数:

template<typename Visitor>
void visit( Visitor &v, const Foo &data )
{
    v.visit( "a", data.a );
    v.visit( "d", data.d );
}
Run Code Online (Sandbox Code Playgroud)

现在我可以以各种方式使用此代码,如果不使用它不应该影响任何东西,例如make std::ostream::operator<<:

struct OstreamVisitor {
    OstreamVisitor( std::ostream &os ) : m_os( os ) {}

    void visit( const char *name, int i ) { m_os << name << "=" << i << std::endl; }
    void visit( const char *name, double d ) { m_os << name << "=" …
Run Code Online (Sandbox Code Playgroud)

c++ templates middleware

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

使用不同类型的容器的迭代器范围初始化容器

假设我们已经std::set<int>并且我们想要创建一个std::vector<int>包含该集合的所有值:

std::set<int> set;
std::vector<int> vec( set.begin(), set.end() );
Run Code Online (Sandbox Code Playgroud)

这很简单而优雅.但是,让我说我有一个std::map<std::string,int>,我想复制所有值std::vector<int>.不幸的是,没有构造函数,它接受迭代器和转换器函数的范围.为什么没有提供这样的构造函数?是否有另一种简单而优雅的方法来初始化具有不同类型值的容器?

c++ stl c++11

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

std :: equal_range与lambda

可以说我有一个字符串向量,我想找到所有以开头的字符串'a',所以我可以这样做:

struct cmp {
    bool operator()( const std::string &s, char c ) const { return s.front() < c; }
    bool operator()( char c, const std::string &s ) const { return s.front() < c; }
};
std::vector<std::string> strings;
...
std::sort( strings.begin(), strings.end() );
auto range = std::equal_range( strings.begin(), strings.end(), 'a', cmp{} );
...
Run Code Online (Sandbox Code Playgroud)

此方法容易出错,因为很容易出错(例如,我认为应该c < s.front()在第二种方法中)并且具有代码重复功能。

那么可以使用通用lambda而不是2种方法来实现比较功能吗?

更笼统的问题是:为什么要比较的值必须作为参数传递给std::lower_boundstd::upper_bound并且std::equal_range何时可以轻松地将其由lambda捕获或传递给比较结构,然后才根本不存在此问题?

如果std::equal_range不要求价值怎么办?

struct cmp {
    cmp( char lc ) : c( lc …
Run Code Online (Sandbox Code Playgroud)

c++ lambda generic-lambda c++14

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

所有基本整数类型的重载是否足以捕获所有整数?

假设我对所有标准整数类型都有函数重载:

void foo( char );
void foo( signed char );
void foo( short );
void foo( int );
void foo( long );
void foo( long long );
// .... all unsigned variants as well
Run Code Online (Sandbox Code Playgroud)

是否有可能这些重载无法找到类似int8_t或类似的类型的适当重载?有可行的方法来处理这种过载吗?

参考怎么样?

澄清问题:它来自对这个问题的讨论为什么int8_t被读作一个字符?并声称可能存在编译器生成的整数类型,它们不是基本C++类型的别名.所以在这种情况下,所有基本情况的重载都可能不接受它.另一方面,我无法提供重载,int8_t因为在许多平台上它只是一个别名,并且会因重新定义现有的重载而出错.

c++ language-lawyer c++11

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

如何确定提取了std :: getline()个字符?

比方说,我读了std::stringstd::istream使用std::getline()过载。如何确定从流中提取了多少个字符?std::istream::gcount()不能像这里讨论的那样工作:ifstream gcount在getline字符串重载时返回0

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    std::istringstream s( "hello world\n" );
    std::string str;
    std::getline( s, str );
    std::cout << "extracted " << s.gcount() << " characters" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

现场例子

请注意,对于下降投票者-字符串的长度不是答案,因为std::getline()可能会或可能不会从流中提取其他字符。

c++ iostream

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