c++11 - Usage of noexcept in derived classes -


i encounter issue while using noexcept specifier on derived classes, more precisely when parent abstract class (has protected constructors).

hereafter example of way declare classes.

  • with public constructor in base class: ok.
  • same code protected , derived class no more "nothrow movable".

do miss something? std::is_nothrow_move_constructible correct traits use in derived class declarations or should use else?

thanks answers.

#include <cstdlib> #include <iostream>  class baseok { public:     baseok ( baseok&& other ) noexcept {} };  class basenok { protected:     basenok ( basenok&& other ) noexcept {} };  class childok : public baseok { public:     childok ( childok&& other ) noexcept ( std::is_nothrow_move_constructible < baseok >::value )         : baseok ( std::move ( other ) ) {} };  class childnok : public basenok { public:     childnok ( childnok&& other ) noexcept ( std::is_nothrow_move_constructible < basenok >::value )         : basenok ( std::move ( other ) ) {} };  int main () {     std::cout << std::boolalpha;     std::cout << "is baseok   move constructible?         " << std::is_move_constructible < baseok >::value << '\n';     std::cout << "is childok  move constructible?         " << std::is_move_constructible < childok >::value << '\n';      std::cout << '\n';     std::cout << "is baseok   nothrow move constructible? " << std::is_nothrow_move_constructible < baseok >::value << '\n';     std::cout << "is childok  nothrow move constructible? " << std::is_nothrow_move_constructible < childok >::value << '\n';      std::cout << '\n';     std::cout << "is basenok  move constructible?         " << std::is_move_constructible < basenok >::value << '\n';     std::cout << "is childnok move constructible?         " << std::is_move_constructible < childnok >::value << '\n';      std::cout << '\n';     std::cout << "is basenok  nothrow move constructible? " << std::is_nothrow_move_constructible < basenok >::value << '\n';     std::cout << "is childnok nothrow move constructible? " << std::is_nothrow_move_constructible < childnok >::value << '\n';     std::cout << std::endl;      return exit_success; } 

output:

 baseok   move constructible?         true  childok  move constructible?         true   baseok   nothrow move constructible? true  childok  nothrow move constructible? true   basenok  move constructible?         false  childnok move constructible?         true   basenok  nothrow move constructible? false  childnok nothrow move constructible? false 

___ edit ____________________________________________________________

after searching around while, , regarding andswer of oleg bogdanov, unfortunately seems not possible combine protected constructors usage of noexcept ( is_nothrow_... ).

i writting abstract classes , declared constructors protected documentation purposes only. now, constructors public i'm facing problem:

as abstract class cannot instanciated, std::is_nothrow_move_constructible<baseclass> returns false , derived classes can never tagged not throwing exceptions if not.

see example below:

#include <cstdlib> #include <iostream>  class foo { public:     foo ( foo&& other ) noexcept {}     virtual ~foo () = 0;  // removing '= 0' makes both outputs print 'true'. }; foo::~foo () {}  class bar : public foo { public:     bar ( bar&& other ) noexcept ( std::is_nothrow_move_constructible < foo >::value )         : foo ( std::move ( other ) ) {} };  int main () {     std::cout << std::boolalpha;     std::cout << "foo: " << std::is_nothrow_move_constructible < foo >::value << '\n';     std::cout << "bar: " << std::is_nothrow_move_constructible < bar >::value << '\n';      return exit_success; } 

output:

foo: false bar: false 

when evaluating true is_move_constructible works is_constructible, in turn says

t object or reference type , variable definition t obj(std::declval()...); well-formed

my guess in case, definition basenok obj(...) not well-formed, because neither have public default ctor (its implicitly removed) nor other accessible ctor (protected not), evals false. (the definition of well-formeness arguable though)

childnok still move_constructible because made move ctor public, other cases eval false because std::is_move_constructible < basenok >::value false


edit: edited question, note section of is_constructible mentions

in many implementations, is_nothrow_constructible also checks if destructor throws because effectively noexcept(t(arg))

when keep destructor pure virtual, fails check.

i not sure if it's oversight or by-design of type traits, issues covered in lwg issue 2116

i'm not proposing scalable solution here, why not mark derived classes unconditionally noexcept now, given base noexcept() too


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -