Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Passing a constexpr member function pointer as template paramter

10 views
Skip to first unread message

bitrex

unread,
Apr 1, 2017, 4:45:13 AM4/1/17
to
Why does the following hack to have each instance of Bar inherit
from a unique "identifier" non-class type, based on the address of the
wrapper class Foo compile with -std=c++17, but not 14 or 11?

struct Foo
{
void type_id() {}
using type_id_t = void (Foo::*)();

struct BarBase
{
virtual ~BarBase();
};

template <void (Foo::*ID)()>
struct Bar : BarBase
{

};

static BarBase* make_base_ptr()
{
constexpr type_id_t id = &Foo::type_id;
return new Bar<id>;
}
};



Marcel Mueller

unread,
Apr 1, 2017, 6:13:46 AM4/1/17
to
On 01.04.17 10.45, bitrex wrote:
> Why does the following hack to have each instance of Bar inherit
> from a unique "identifier" non-class type, based on the address of the
> wrapper class Foo compile with -std=c++17, but not 14 or 11?

No idea what inheritance you mean within this context, but with
constexpr is up to the compiler to evaluate it at compile time or at run
time. So the fragment
> constexpr type_id_t id = &Foo::type_id;
> return new Bar<id>;
may not work because id might be evaluated at run time. But
return new Bar<&Foo::type_id>;
works even with C++11.


Marcel

Alf P. Steinbach

unread,
Apr 1, 2017, 6:36:51 AM4/1/17
to
On 01-Apr-17 12:13 PM, Marcel Mueller wrote:
> On 01.04.17 10.45, bitrex wrote:
>> Why does the following hack to have each instance of Bar inherit
>> from a unique "identifier" non-class type, based on the address of the
>> wrapper class Foo compile with -std=c++17, but not 14 or 11?
>
> No idea what inheritance you mean within this context, but with
> constexpr is up to the compiler to evaluate it at compile time or at run
> time. So the fragment
>> constexpr type_id_t id = &Foo::type_id;
>> return new Bar<id>;
> may not work because id might be evaluated at run time.

No, you're conflating with `constexpr` functions.

`constexpr` on a variable forces compile time; that's a way to test that
a `constexpr` function call can really be done at compile time.

I think that simply due to some peculiarity of the literal rules, the
initializer is not considered a compile time expression in C++14 and
earlier. Just my gut feeling, though.


> But
> return new Bar<&Foo::type_id>;
> works even with C++11.

Cheers!,

- Alf


Alvin

unread,
Apr 1, 2017, 7:12:23 AM4/1/17
to
0 new messages