C++11 / Non Constructible but Copyable? - c++11

I observed that if I explicitly delete only constructor and destructor of a class then the resultant implementation deletes copy constructor & move constructor, but the compiler still makes copy assignment and move assignment operators implicitly available! Which in turn makes assignment possible!
My question is what is the rational of this? What is the use case where this can be used. Following is an example code for reference:
# ifndef MOEGLICH_H_
# define MOEGLICH_H_
# include <cstdint>
class Moeglich final
{
public :
explicit
Moeglich() = delete ;
~Moeglich() = delete ;
/*
// With explicit deletion
Moeglich& operator=(const Moeglich& other) = delete ;
Moeglich(const Moeglich& other) = delete ;
Moeglich&& operator=(Moeglich&& other) = delete ;
Moeglich(Moeglich&& other) = delete ;
*/
static constexpr uint16_t Egal(const uint8_t& var_) noexcept
{
return static_cast< uint16_t > ( var_ ) ;
}
};
# endif
# include <cstdlib>
# include <iostream>
# include <type_traits>
int main(int argc, char* argv[])
{
std::cout << std::boolalpha
<< "Is constructible : " << std::is_constructible<Moeglich>::value << std::endl
<< "Is destructible : " << std::is_destructible<Moeglich>::value << std::endl
<< "Is copy constructible : " << std::is_copy_constructible<Moeglich>::value << std::endl
<< "Is move constructible : " << std::is_move_constructible<Moeglich>::value << std::endl
<< "Is copy assignable : " << std::is_copy_assignable<Moeglich>::value << std::endl
<< "Is move assignable : " << std::is_move_assignable<Moeglich>::value << std::endl
<< "Is assignable : " << std::is_assignable<Moeglich, Moeglich>::value << std::endl
;
/* Following were what I wanted to prevent anyway :
const Moeglich mom {} ;
Moeglich pop {} ;
Moeglich foo {} ;
foo = mom ;
foo = std::move(pop) ;
*/
return EXIT_SUCCESS ;
}
Edit:: I see I have created a lot of confusion by vaguely putting some codes and not mentioning intent. I will never construct this object. All I am interested is accessing
const uint8_t duh { 5 } ;
const uint16_t notEgal { Moeglich::Egal(duh) } ;
Here is what is important for me: Sometimes, I need partial template specialization of functions which is not allowed which can be enabled if I put this function inside a template class.
I have been pointed to a link here, which very clearly lays down the rule. My expectation from the compiler was wrong and my use-case cannot be understood in a special way by the compiler.
Thanks everybody for commenting.
Regards,
Sumit

Related

Selecting which overload is used in c++11

In the following code, as none of the arguments is const, i can't understand why the second overload is called in the 3 following cases.
#include <iostream>
#include <algorithm>
using namespace std;
void ToLower( std::string& ioValue )
{
std::transform( ioValue.begin(), ioValue.end(), ioValue.begin(), ::tolower );
}
std::string ToLower( const std::string& ioValue )
{
std::string aValue = ioValue;
ToLower(aValue);
return aValue;
}
int main()
{
string test = "test";
cout<<"Hello World" << endl;
// case 1
cout << ToLower("test") << endl;
// case 2
cout << ToLower(static_cast<string>(test)) << endl;
// case 3
cout << ToLower(string(test)) << endl;
}
In all 3 cases you are creating a temporary std::string, this is an unnamed object, an R-value. R-values aren't allowed to bind to non-const l-value references (T&) and so only the overload taking const std::string& ioValue is valid.
The reasoning is the return type is std::string for the second function but void for the first. std::cout << (void) << std::endl is not a valid set of operations. std::cout << (std::string) << std::endl is. If you return a std::string& from the first function you'd probably see #2 & #3 probably use your first function call.

Can I use an alias for static member function templates?

Using C++11, I'd like to call a static member function template without qualifying it with the scope of its enclosing class:
struct Test {
template<typename T>
static bool Function(T x)
{ /* ... */ }
};
int x;
Test::Function(x); // I don't want to write this
Function(x); // I want to be able to write this instead
I can define another function with the same signature at global scope and forward the arguments, but I'd prefer a solution that doesn't force me to write another function. I'd also like to avoid using a macro.
This question is related:
(using alias for static member functions?)
but doesn't seem to cover the case of function templates.
Sure, you can alias the templated function if you want to do a little work with the using keyword first:
template<typename T>
using testfn = bool (*)(T);
and then create a pointer to the function with:
testfn<int> fnPointer = Test::Function;
and finally call it:
std::cout << boolalpha << fnPointer(x) << std::endl;
Live Demo
If you only ever want to bind to the case where T is int, you can do this:
using testfn = bool (*)(int);
//...
testfn fnPointer = Test::Function;
std::cout << boolalpha << fnPointer(x) << std::endl;
Live Demo 2
Edit: If you want a constexpr function pointer like in the accepted answer of the question you linked, that's a pretty simple extension:
constexpr auto yourFunction = &Test::Function<int>;
//...
std::cout << boolalpha << yourFunction(x) << std::endl;
Live Demo 3
I learned this playing with the #andyg answer (probably above mine), but it worked for me and it doesn't require putting a different alias for every template.
It requires c++14 or later though.
Step 1 - magical template alias:
template <typename T> constexpr auto funky1 = &Test::Function<T>;
Step 2 - lambda means you don't need to pass the template argument:
auto funky = [](auto in) { return funky1<decltype(in)>(in); };
full example
Also, inline full example:
#include <iostream>
struct Test {
template <typename T> static bool Function(T x) { return true; }
};
// Magical template alias
template <typename T> constexpr auto funky1 = &Test::Function<T>;
// lambda means it'll infer the template parameters when calling
auto funky = [](auto in) { return funky1<decltype(in)>(in); };
int main() {
int x = 0;
// Just use the `funky1` version, but you have to specify the template parameters
std::cout << "string: " << funky1<std::string>("I'm a string") << std::endl
<< "int: " << funky1<int>(42) << std::endl
<< "bool: " << funky1<bool>(true) << std::endl;
// Use the `funky` version, where template parameters are inferred
std::cout << "string: " << funky("I'm a string") << std::endl
<< "int: " << funky(42) << std::endl
<< "bool: " << funky(true) << std::endl;
return 0;
}

Output to logging class via operator<<

I have implemented a logging class TLogFile and now I want to overload the output operator<<.
I want to use the log like this:
TLogFile* log = new TLogFile("some arguments...");
*log << "Hello world."; // (1)
*log << "Hello world." << endl; // (2)
*log << std::hex << setw(2) << setfill('0') << someValue << endl; // (3)
I used ostream as a class member and as a friend. The class looks like this:
namespace app {
class TLogFile
{
public:
app::TLogFile& operator<< (std::string& out);
std::ostream& operator<< (std::ostream& out);
friend std::ostream& operator<< (std::ostream& out, TLogFile& o);
};
} // namespace app
Only plain text (1) is working by using the string version. A soon as I use endl (2) or iomanip (3) I get error messages:
../src/main.cpp:164:70: error: no match for 'operator<<' in 'sysdat.app::cSystemData::obj.app::cSystemObjects::applicationLog->app::TLogFile::operator<<((* & std::basic_string(((const char*)"sysdat.obj.applicationLog <<"), ((const std::allocator*)(& std::allocator()))))) << std::endl'
../src/main.cpp:164:70: note: candidates are:
../src/inc/logger.h:85:17: note: app::TLogFile& app::TLogFile::operator<<(const string&)
../src/inc/logger.h:85:17: note: no known conversion for argument 1 from '' to 'const string& {aka const std::basic_string&}'
../src/inc/logger.h:88:17: note: std::ostream& app::TLogFile::operator<<(std::ostream&)
../src/inc/logger.h:88:17: note: no known conversion for argument 1 from '' to 'std::ostream& {aka std::basic_ostream&}'
../src/inc/logger.h:93:23: note: std::ostream& app::operator<<(std::ostream&, app::TLogFile&)
../src/inc/logger.h:93:23: note: no known conversion for argument 1 from 'app::TLogFile' to 'std::ostream& {aka std::basic_ostream&}'
I believed that one of the ostream version should work.
Has anyone an idea how to overload the operator so that endl and iomanip can be used?
Your operator<< is able to take only std::ostream& and std::string&
(note: probably it should be const std::string&).
The most elegant solution I can imagine is to write a template:
class TLogFile{
protected:
std::ostream* stream;
public:
/* default ctor, copy ctor and assignment operator: */
TLogFile(std::ostream& _stream=std::clog):stream(&_stream){}
TLogFile (const TLogFile&) =default;
TLogFile& operator= (const TLogFile&) =default;
/* std::endl is overloaded,
* so I think compiler doesn't know which version to use.
* This funchtion handles function pointers, including std::endl
*/
inline TLogFile& operator<< (std::ostream&(*func)(std::ostream&)){
(*stream) << func;
return *this;
}
/* should handle everything else */
template<typename T>
inline TLogFile& operator<< (const T& t) {
(*stream) << t;
return *this;
}
}
See it working in online compiler
This way your objects' operator<<s should be able to take anything that std::ostream's can take.
Edit:
Next time, please say that you want to have custom std::endl.
I'm not sure that function with signature
inline TLogFile& operator<< (std::ostream&(*func)(std::ostream&))
is used only when std::endl is passed to it. My previous solution seems inelegent or even inworking. I'm wondering about how to change behaviour of std::endl when it's passed to object of different class.
Notes:
In most cases I'd like to use '\n instead of std::endl.
TLogFile* log = new TLogFile("some arguments...");
I think using raw pointer isn't the best idea here (it's easy to forget about delete),
unless you have to explicitly decide when the object should die.
When the object should die when the current scope does, it should be a local variable:
TLogFile log("some arguments...");
//Usage:
log << "Hello world."; // (1)
log << "Hello world." << endl; // (2)
log << std::hex << setw(2) << setfill('0') << someValue << endl; // (3)
If the object is used in multiple places, and each of the places uses it independently from others, IMO the best solution is to use std::shared_ptr:
#include <memory>
#include <utility>
auto log=std::make_shared<TLogFile>("some arguments...");
//Usage:
*log << "Hello world."; // (1)
*log << "Hello world." << endl; // (2)
*log << std::hex << setw(2) << setfill('0') << someValue << endl; // (3)
This way the object dies when the last shared_ptr does.
I used pointer in the class to be able to re-assign it. If you don't need re-assignment, you can use reference instead.
Thanks to GingerPlusPlus. I found out, that the operator operator<< (std::ostream&(*func)(std::ostream&)) is called only once for the endl (maybe this assumtion is not always true, Please read remarks/edit above of GingerPlusPlus). I replaced the ostream against a stringstream and write the contens of the stringstream when the operator ist called.
class TLogFile{
protected:
std::ostream* stream;
std::stringstream line;
public:
/* default ctor, copy ctor and assignment operator: */
TLogFile(std::ostream& _stream=std::clog):stream(&_stream){}
TLogFile (const TLogFile&) =default;
TLogFile& operator= (const TLogFile&) =default;
void write() {
// Doing some write stuff
// ...
// Empty stringstream buffer
line.str(std::string());
}
/* std::endl is overloaded,
* so I think compiler doesn't know which version to use.
* This funchtion handles function pointers, including std::endl
*/
inline TLogFile& operator<< (std::ostream&(*func)(std::ostream&)){
line << func;
write();
return *this;
}
/* should handle everything else */
template<typename T>
inline TLogFile& operator<< (const T& t) {
line << t;
return *this;
}
}

Is it possible/legal to return reference to input temporary arguments which are passed by reference

My question is : is it legal to return a reference to an input variable which is passed by reference.
I borrow the example from C++: Life span of temporary arguments? and return by rvalue reference
#include <iostream>
#include <string>
class MatrixClass
{
public:
int m_value;
std::string m_str;
MatrixClass(int a)
{
m_value = a;
std::cout << "hello: " << m_value << '\n';
}
MatrixClass(const MatrixClass& A)
{
m_value = A.m_value;
std::cout << "hello: " << m_value << '\n';
if (A.m_str == "temp_in_*")
{
std::cout << "string: " << "copied from temp_in_*" << '\n';
}
}
void operator=(const MatrixClass& A)
{
m_value = A.m_value;
std::cout << "hello: " << m_value << '\n';
if (A.m_str == "temp_in_*")
{
std::cout << "string: " << "copied from temp_in_*" << '\n';
}
}
~MatrixClass()
{
std::cout << "bye: " << m_value << '\n';
if (m_str == "temp_in_*")
{
std::cout << "string: " << "temp_in_*" << '\n';
}
}
};
MatrixClass& operator+(MatrixClass& tempClassA, MatrixClass& tempClassB)
{
tempClassA.m_value += tempClassB.m_value;
return tempClassA;
}
MatrixClass operator*(MatrixClass& tempClassA, MatrixClass& tempClassB)
{
MatrixClass Temp(101010);
Temp.m_value = tempClassA.m_value * tempClassB.m_value;
Temp.m_str = "temp_in_*";
return Temp;
}
int main()
{
MatrixClass A1(2);
MatrixClass A2(3);
MatrixClass A3(10);
MatrixClass A4(11);
MatrixClass A5(12);
std::cout << "start of expression " << '\n';
MatrixClass A6(0);
A6 = A1 * A2 + A3 * A4 + A5 * A6;
std::cout << "end of expression " << '\n';
std::cout << "A6.m_value: " << A6.m_value << '\n';
std::system("pause");
}
the operator return a reference to its input which is a temporary variable, and pass
it to another operator: operator*(A1, A2) return a temporary variable, also operator*(A3, A4), operator*(A5, A6)
Is there any problem with the lifetime of the temporary variables ? I am developing a Matrix class.
What happens if the expression is more complicated, such as:
(A+B*C)*((A*B + C)*A)
A general question is (take from return by rvalue reference)
is this possible:
change
A compute(A&& v)
{
(do something to v)
return v;
}
to
A& compute(A& v)
{
(do something to v)
return v;
}
Yes, it is legal for a function to return references to input parameters, in the sense that it will compile and there are many uses where it will work without problems. The lifetime of any temporaries created in an expression is the lifetime of the full expression or statement, so as long as the reference is not used beyond the expression, the usage should work fine. It is somewhat risky, though, because the caller may not be aware of the reference propagation the function does, and the special rules for extension of temporary lifetimes don't generally apply when the reference is passed through an intermediary function.
Your examples involve modifying and returning a reference to non-const lvalue instance. These types of uses, in general, will be harder to run into the pitfalls than references to const or references to rvalues. A reference to non-const lvalue can't be bound to a temporary (at least not without going through some hoops to trick the compiler), so you will generally have to pass an actual l-value (non-temporary) named variable (or other long-lived object) into them. When that reference is then passed out of the function as a return value, it will refer to whatever long-lived object was passed in. (You can still get into trouble if you don't properly manage lifetimes, of course, but at least the lifetimes we're talking about in this case are generally more than a single statement/expression.)
If you pass rvalue references through your function, and especially if they get translated to a non-const lvalue somewhere down the expression tree (which is somewhat easy to do since the language, as a safety feature, decays rvalues into lvalues whenever they're bound to a name), the temporary nature of the reference can be lost and it is easier to accidentally bind the reference to a long-lived reference, which would outlive the temporary that it is bound to (which generally won't live beyond the statement/full-expression in which it is created). This is why I generally favor returning (and usually passing) r-values by value rather than by reference. Then, the compiler is more aware of the lifetime issues and the usages are generally more foolproof. In many cases, the compiler can elide the move constructions anyway, and when it can't, moves are generally cheap.

C++11 Struct definition with atomic attribute

In C++11 I have a struct with lots of attributes like so:
#include <atomic>
struct Foo {
int x;
int y;
// ...
// LOTS of primitive type attributes, followed by...
// ...
std::atomic_bool bar;
}
And I'd like to define an instance like so:
bool bar_value = true;
Foo my_foo = {/*attribute values*/, bar_value};
However, the atomic_bool is throwing a "use of deleted function" error because I think copy constructing is not allowed on atomics. Is there any way around this, short of writing out a constructor or assigning each value individually?
It just seems inconvenient to have to treat this otherwise relatively banal struct in a special way just because one of its many attributes is a special case.
Updates:
Any takers? I've been looking around, but there doesn't seem to be any straightforward way to resolve this.
Try wrapping the initialization of the atomic_bool in its own initializer list. It worked for me in g++ 4.7.
#include <atomic>
#include <iostream>
struct Foo
{
int x;
int y;
std::atomic_bool bar;
};
int main(int, char**)
{
Foo f1 = {1, 2, {true}};
Foo f2 = {3, 4, {false}};
std::cout << "f1 - " << f1.x << " " << f1.y << " "
<< (f1.bar.load()?"true":"false") << std::endl;
std::cout << "f2 - " << f2.x << " " << f2.y << " "
<< (f2.bar.load()?"true":"false") << std::endl;
}
I got the following output:
$ g++ -std=c++11 test.cpp -o test && ./test
f1 - 1 2 true
f2 - 3 4 false

Resources