Boost :: proto :: is_aggregate returns false when it is an aggregate type

When testing aggregate types, I tried using boost :: proto :: is_aggregate to check if the types that I create are really aggregate. I wrote this code:

#include <iostream>
#include <boost\proto\traits.hpp>

struct IsAggregate
{
    IsAggregate &operator=(IsAggregate const &rhs) {}
};

int main()
{
    std::cout << std::boolalpha;
    std::cout << boost::proto::is_aggregate<IsAggregate>() << std::endl;

    return 0;
}

And I expected that the output would be true, since the types of aggregates can be determined by the copy-assignment operator (according to this: What are aggregates and PODs and how / why are they special? )

But the conclusion is false.

I also used aggregate classes inside the previous answer, which were supposed to return true, but instead return false.

This has been tested on Boost 1.5.9 with both the Intel compiler and MSVC.

Any ideas on why this happened?

+4
1

.

POD, 3 - . , , , , ( make<> , T{} T()).


, , , , . , , .

:

. , , is_pod is_literal_type, , .

     

, (, " -init-list?" ), ephemera (, " " , , ? "" ? ").

     

, , , , - .

/ . , ,

( 10)

, (, ..) .

, , , :

template <typename T>
struct is_aggregate : std::integral_constant<bool,
        std::is_pod<T>() or
        (
                std::is_trivially_constructible<T>() 
            and std::is_trivially_destructible<T>()
            and std::is_standard_layout<T>()
            and not std::is_polymorphic<T>()
        )
    >
{ };

, , , , //, Proto.

CAVEAT. ++ 11/++ 14 ( , ,). , , ( , MSVC, ), /.

Live On Coliru

#include <iostream>
#include <type_traits>
#include <string>

template <typename T>
struct is_aggregate : std::integral_constant<bool,
        std::is_pod<T>() or
        (
                std::is_trivially_constructible<T>() 
            and std::is_trivially_destructible<T>()
            and std::is_standard_layout<T>()
            and not std::is_polymorphic<T>()
        )
    >
{ };

namespace simple { // ok
    struct X {
        int x;
        X &operator=(X const &/*rhs*/) { return *this; }
    };

    static_assert(is_aggregate<X>(), "");

    void foo() { X x { 42 }; (void) x; }
}

namespace usr_defined_ctor { // NOT ok
    struct X {
        int x;
        X &operator=(X const &/*rhs*/) { return *this; }

        X() {}
    };

    static_assert(!is_aggregate<X>(), "");

    //void foo() { X x { 42 }; (void) x; }
}

namespace defaulted_ctor { // ok
    struct X {
        int x;
        X &operator=(X const &/*rhs*/) { return *this; }

        X() = default;
    };

    static_assert( is_aggregate<X>(), "");

    void foo() { X x { 42 }; (void) x; }
}

namespace static_data_members { // ok
    struct X {
        int x;
        X &operator=(X const &/*rhs*/) { return *this; }

        X() = default;

        static const bool yeah = true;
    private:
        static const bool no = true;
    protected:
        static const std::string problem;
    };

    bool const X::yeah;
    bool const X::no;
    std::string const X::problem = "whatsoever";

    static_assert( is_aggregate<X>(), "");

    void foo() { X x { 42 }; (void) x; }
}

namespace private_non_static_data_members { // NOT ok
    struct X {
        int x;
        X &operator=(X const &/*rhs*/) { (void) oops; return *this; }

    private:
        bool oops;
    };

    static_assert(!is_aggregate<X>(), "");

    //void foo() { X x { 42, true }; (void) x; }
}

namespace protected_non_static_data_members { // NOT ok
    struct X {
        int x;
        X &operator=(X const &/*rhs*/) { return *this; }

    protected:
        bool oops;
    };

    static_assert(!is_aggregate<X>(), "");

    //void foo() { X x { 42, true }; (void) x; };
}

namespace have_base_class { // NOT ok
    struct B {};
    struct X : B {
        int x;
        X &operator=(X const &/*rhs*/) { return *this; }
    };

    static_assert(is_aggregate<X>(), ""); // FALSE POSITIVE: the below fails to compile

    //void foo() { X x { 42 }; (void) x; };
}

int main() { }

Coliru ( ) :

g++ -std=c++0x -O2 -Wall -pedantic -pthread main.cpp
g++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp
g++ -std=c++1y -O2 -Wall -pedantic -pthread main.cpp
g++ -std=c++1z -O2 -Wall -pedantic -pthread main.cpp
clang++ -std=c++0x -O2 -Wall -pedantic -pthread main.cpp
clang++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp
clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp
clang++ -std=c++1y -O2 -Wall -pedantic -pthread main.cpp
clang++ -std=c++1z -O2 -Wall -pedantic -pthread main.cpp
clang++ -stdlib=libc++ -std=c++0x -O2 -Wall -pedantic -pthread main.cpp
clang++ -stdlib=libc++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp
clang++ -stdlib=libc++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp
clang++ -stdlib=libc++ -std=c++1y -O2 -Wall -pedantic -pthread main.cpp
clang++ -stdlib=libc++ -std=c++1z -O2 -Wall -pedantic -pthread main.cpp
+6

Source: https://habr.com/ru/post/1615381/


All Articles