Search code examples
c++11decltypenoexcept

C++11 - How to fix noexcept operator that fails to detect function declaration with noexcept specifier


I'm setting up a new library for personal research purpose, and i'm trying to fully understand c++ standard library tools and core functionalities. Now i have a problem understanding the noexcept operator.

I wrote some test examples involving the noexcept operator and i'm puzzled with the result of the following assertion:

...
void no_throw() noexcept;

static_assert(noexcept(no_throw), "This should be true");
static_assert(noexcept((std::declval<decltype(no_throw)>())()), "this also should be true");
...

I expected this code to compile, but the second assertion pass only if using c++17 compile flag; i did run the test with gcc8.1 and clang5.0 . I've not tested with other compilers.

It fails with c++11 or c++14 flag. Could someone explain me why?

Thank you


Solution

  • Your first test, don't work: This pass

    void no_throw() noexcept(true) {};
    void do_throw() noexcept(false) {};
    
    static_assert(noexcept(no_throw), "");
    static_assert(noexcept(do_throw), "");
    

    Should be :

    void no_throw() noexcept(true) {};
    void do_throw() noexcept(false) {};
    
    static_assert(noexcept(no_throw()), "");
    static_assert(!noexcept(do_throw()), "");
    

    Then why only in 17 :

    Until 17 : The noexcept-specification is not a part of the function type source : https://en.cppreference.com/w/cpp/language/noexcept_spec

    So if you run this code in 11 :

    template<class T>
       struct TD;
    
    TD<decltype(no_throw)> e;
    TD<decltype(std::declval<decltype(no_throw)>())> e2;
    

    You got :

    prog.cc:14:24: error: aggregate 'TD<void()> e' has incomplete type and cannot be defined
     TD<decltype(no_throw)> e;
                            ^
    prog.cc:15:50: error: aggregate 'TD<void (&)()> e2' has incomplete type and cannot be defined
     TD<decltype(std::declval<decltype(no_throw)>())> e2;
    

    And in 17 :

    prog.cc:14:24: error: aggregate 'TD<void() noexcept> e' has incomplete type and cannot be defined
     TD<decltype(no_throw)> e;
                            ^
    prog.cc:15:50: error: aggregate 'TD<void (&)() noexcept> e2' has incomplete type and cannot be defined
     TD<decltype(std::declval<decltype(no_throw)>())> e2;
    

    See, in 17 the noexcept is now in the type