考虑以下代码:
#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 ++ …
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上的错字吗?
在cpprefernce.com 前缀增量的示例中,有这样的代码:
int n1 = 1;
...
int n3 = ++ ++n1;
Run Code Online (Sandbox Code Playgroud)
为什么在这种情况下链式增量不会导致UB?在这种情况下,最多一次修改的规则是否违反?
假设我们上课了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()
?
假设我们存储一个带有字符串键的结构,我们希望通过容器中的字符串找到它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)
这样可以正常工作,但是编写三种方法的FooComp
prety匹配相同(逻辑上)是单调的,容易出错.有没有办法最小化该代码?
我们使用中间件为我们生成各种编程语言类型,包括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) 假设我们已经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>
.不幸的是,没有构造函数,它接受迭代器和转换器函数的范围.为什么没有提供这样的构造函数?是否有另一种简单而优雅的方法来初始化具有不同类型值的容器?
可以说我有一个字符串向量,我想找到所有以开头的字符串'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_bound
,std::upper_bound
并且std::equal_range
何时可以轻松地将其由lambda捕获或传递给比较结构,然后才根本不存在此问题?
如果std::equal_range
不要求价值怎么办?
struct cmp {
cmp( char lc ) : c( lc …
Run Code Online (Sandbox Code Playgroud) 假设我对所有标准整数类型都有函数重载:
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
因为在许多平台上它只是一个别名,并且会因重新定义现有的重载而出错.
比方说,我读了std::string
从std::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()
可能会或可能不会从流中提取其他字符。