为什么在运行时调用这个右值constexpr构造函数?

时间:2017-06-09 18:56:01

标签: c++ constexpr

为什么下面的代码会将前一种情况下A类的使用视为constexpr而不是第三种情况?我已尝试使用4.9到7.1的各种版本的gcc,并且每次都会遇到相同的行为。我在这里缺少什么?

template <std::size_t N> struct B{};

class A
{
public:
    constexpr A(std::size_t value):value_(value){}
    std::size_t const value_;
};


std::int32_t main
(
    std::int32_t,
    char const **
)
{
    A a(1);           // expected - constructor not invoked at run time
    B<A(1).value_> b; // expected - compiles so clearly constexpr
    A(1);             // *** unexpected *** - invokes the constructor at run time, why?
    return 0;
}

使用更全面的示例进行了更新

template <std::size_t N> 
struct B
{
    constexpr std::size_t dont_optimize_me_out
    (
    )
    {
        return 0;
    }
};


constexpr std::size_t some_hash
(
    char const *,
    std::size_t
)
{
    return 0;
}


class hashed_id
{
public:

    template <std::size_t N>
    constexpr hashed_id
    (
        char const (&input)[N]
    ):
        value_(some_hash(input, N - 1))
    {
    }

    constexpr hashed_id
    (
        std::size_t value
    ):
        value_(value)
    {
    }

    constexpr std::size_t get_value
    (
    )
    {
        return value_;
    }

private:

    std::size_t const value_;
};


class A
{
public:

    constexpr A
    (
        hashed_id id
    ):
        id_(id)
    {
    }

    constexpr hashed_id get_id
    (
    )
    {
        return id_;
    }

    constexpr std::size_t dont_optimize_me_out
    (
    )
    {
        return id_.get_value();
    }

private:

    hashed_id const id_;
};


int main
(
    int,
    char const **
)
{
    std::size_t k = 0;

    A a("foo"); // expected - constructor not invoked at run time
    k += a.dont_optimize_me_out();

    B<A("foo").dont_optimize_me_out()> b; // expected - compiles so clearly constexpr
    k += b.dont_optimize_me_out();

    k += A("foo").dont_optimize_me_out(); // *** unexpected *** - invokes the constructor (and hash function) at run time, why?

    std::cout << k << std::endl;
    return 0;
}

0 个答案:

没有答案