language-lawyer

Is the following use of const_cast undefined behavior?

落爺英雄遲暮 提交于 2019-12-19 00:57:23
问题 This is a language lawyer question, not a good practice question. Is the following code valid or undefined behaviour? A const object ends up calling a non-const function, but it doesn't actually modify the state of the object. struct Bob { Bob() : a(0) {} int& GetA() { return a; } const int& GetA() const { return const_cast<Bob&>(*this).GetA(); } int a; }; int main() { const Bob b; int a = b.GetA(); } 回答1: The behavior is well-defined : C++ standard, section § 5.2.11/7 [const cast] [ Note:

Which compiler, if any has a bug in parameter pack expansion?

泪湿孤枕 提交于 2019-12-18 19:40:23
问题 When experimenting with convenient ways to access tuples as containers, I wrote a test program. on clang (3.9.1, and apple clang) it compiles as expected, producing the expected output: 1.1 foo 2 on gcc (5.4, 6.3), it fails to compile: <source>: In lambda function: <source>:14:61: error: parameter packs not expanded with '...': +[](F& f, Tuple& tuple) { f(std::get<Is>(tuple)); }... ^ <source>:14:61: note: 'Is' <source>: In function 'decltype(auto) notstd::make_callers_impl(std::index_sequence

variadic templates - ambiguous call

笑着哭i 提交于 2019-12-18 19:27:09
问题 The following code compiles in both gcc 4.7.2 and MSVC-11.0: template <typename T> void foo(T bar) {} template <typename T, typename... Args> void foo(T bar, Args... args) {} int main() { foo(0); // OK } Why? I think that it's must be ambiguous call: ISO/IEC 14882:2011 14.5.6.2 Partial ordering of function templates [temp.func.order] 5 ... [ Example: template<class T, class... U> void f(T, U...); // #1 template<class T > void f(T); // #2 template<class T, class... U> void g(T*, U...); // #3

Evaluating stream operator >> as boolean

試著忘記壹切 提交于 2019-12-18 19:22:11
问题 The following code compiles in Visual Studio 2008 but fails in Visual Studio 2013 and later. std::string str("foo"); std::stringstream ss(str); float f = 0; if ((ss >> f) == false) std::cout << "Parse error\n"; The error message is error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_istream>' (or there is no acceptable conversion) and is successfully fixed by changing as follows: if (!(ss >> f)) std::cout << "Parse error\n"; I'm not understanding

Is vector::insert allowed to reserve only once and avoid further capacity checks?

点点圈 提交于 2019-12-18 18:56:11
问题 vector::insert(dst_iterator, src_begin, src_end) (insert a range) can be optimized for random-access iterators to reserve the required capacity src_end - src_begin first, then perform the copy. The main question I have: Does the Standard also allow vector::insert to avoid a capacity check for each copied element? (I.e. not using push_back or similar on every element to be inserted) I'll refer to avoiding this capacity check as "optimization of insert ". What could go wrong: I can imagine an

type of reference-captured object inside lambda

笑着哭i 提交于 2019-12-18 18:51:52
问题 The following code works with gcc #include <map> int main() { std::map<int, double> dict; const auto lambda = [&]() { decltype(dict)::value_type bar; }; } But for msvc I have to additionally use std::remove_reference #include <map> #include <type_traits> int main() { std::map<int, double> dict; const auto lambda = [&]() { std::remove_reference_t<decltype(dict)>::value_type bar; }; } Otherwise I get an error: error C2651: 'std::map<int,double,std::less<_Kty>,std::allocator<std::pair<const _Kty

type of reference-captured object inside lambda

偶尔善良 提交于 2019-12-18 18:49:58
问题 The following code works with gcc #include <map> int main() { std::map<int, double> dict; const auto lambda = [&]() { decltype(dict)::value_type bar; }; } But for msvc I have to additionally use std::remove_reference #include <map> #include <type_traits> int main() { std::map<int, double> dict; const auto lambda = [&]() { std::remove_reference_t<decltype(dict)>::value_type bar; }; } Otherwise I get an error: error C2651: 'std::map<int,double,std::less<_Kty>,std::allocator<std::pair<const _Kty

Since the Standard C committee did not standardize a simple replacement for gets(), what should it be?

…衆ロ難τιáo~ 提交于 2019-12-18 18:47:32
问题 The gets function was first deprecated in C99 and finally removed in C11. Yet there is no direct replacement for it in the C library. fgets() is not a drop-in replacement because it does not strip the final '\n' , which may be absent at the end of file. Many programmers get it wrong too. There is a one-liner to remove the linefeed: buf[strcspn(buf, "\n")] = '\0'; , but it is non-trivial and often calls for an explanation. It may be inefficient as well. This is counter-productive. Many

Does a reference have a storage location?

一个人想着一个人 提交于 2019-12-18 18:40:56
问题 Does a reference have a storage location or is it just an alias for another location? Does this differ by C++ revision or is it consistent with all versions of C++? And if a reference has a storage location, does it then just allow value semantics on a pointer like type? How would a reference work when you use it as such: struct aStruct{ int aVariable; aClass& aReferencetoaClass; }; Does it take up space or is it an alias? 回答1: The latest C++20 spec(§ 9.2.3.3) and at least since the C++ 2005

Can calloc() allocate more than SIZE_MAX in total?

℡╲_俬逩灬. 提交于 2019-12-18 18:37:33
问题 In a recent code review, it was claimed that On select systems, calloc() can allocate more than SIZE_MAX total bytes whereas malloc() is limited. My claim is that that's mistaken, because calloc() creates space for an array of objects - which, being an array, is itself an object. And no object can be larger in size than SIZE_MAX . So which of us is correct? On a (possibly hypothetical) system with address space larger than the range of size_t , is calloc() allowed to succeed when called with