if constexpr in class declaration

800 views
Skip to first unread message

Cleiton Santoia

unread,
Aug 9, 2016, 1:30:47 PM8/9/16
to ISO C++ Standard - Future Proposals
"If constexpr" is defined only as statement, someone thought about allow it into class definitions like this :

template <class T>
struct X {
   
if constexpr (std::is_arithmetic_v<T>) {
     
double value;
   } else constexpr {
     std
::string value;
   
}
};

X
<int>::value     // value is double
X
<Myclass>::value // value is string

I know that this particular example will be better with concepts, but the question remains... 


Richard Smith

unread,
Aug 9, 2016, 1:56:22 PM8/9/16
to std-pr...@isocpp.org
Yes, it's been thought about, but this is doing something fundamentally different from what 'if constexpr' does, and it has major practical problems. You can look through the history of papers on constexpr if and static if for a taste of the problems.

rhalb...@gmail.com

unread,
Aug 9, 2016, 6:01:33 PM8/9/16
to ISO C++ Standard - Future Proposals


On Tuesday, August 9, 2016 at 7:56:22 PM UTC+2, Richard Smith wrote:

Yes, it's been thought about, but this is doing something fundamentally different from what 'if constexpr' does, and it has major practical problems. You can look through the history of papers on constexpr if and static if for a taste of the problems.

I understand that applying if-constexpr to conditional data member layout is different because a regular if cannot appear at class scope. But reading the static if papers and their critiques, the supplied alternative to the OP's example using partial specializations, tuple and empty base class trickery do not really provide a superior alternative. Optimal class layout is currently cumbersome, using if-constexpr would make this a lot easier for users. 

What exactly would be making it hard (compared to if-constexpr at function scope) for the compiler to do the conditional data layout using if-constexpr?

Richard Smith

unread,
Aug 9, 2016, 7:12:16 PM8/9/16
to std-pr...@isocpp.org
Just a taste:

int value;
template<typename T> struct X {
  some_kind_of_static_if (is_fooable_v<T>) {
    T value;
  }
  int f() { return value; }
};

Edward Catmur

unread,
Aug 9, 2016, 7:27:38 PM8/9/16
to ISO C++ Standard - Future Proposals
Well, quite; does the name lookup of value within X::f depend on the type of T? Or did you mean to write this->value, as you'd have to with a dependent base?

Note that this particular case (a single data member with dependent type) is perfectly well served by std::conditional. If there was any prospect of getting mixins I'd argue that that would be a mostly satisfactory solution and wouldn't require any new lookup rules.

rhalb...@gmail.com

unread,
Aug 17, 2016, 5:44:06 AM8/17/16
to ISO C++ Standard - Future Proposals
How is that different from

int value;

template<typename T> int f()
{
    some_kind_of_static_if(is_fooable_v<T>) {
        return value;
    } else {
        int value = 42;
        return value;
   }

Won't there be a warning about shadowing a global variable in both cases?

D. B.

unread,
Aug 17, 2016, 6:05:49 AM8/17/16
to std-pr...@isocpp.org
I think the point was that by making the existence of member T conditional, you'd then have to do the same for the function f() that uses it, and everything else.

Your situation seems to do something totally different.

Edward Catmur

unread,
Aug 17, 2016, 9:21:08 AM8/17/16
to std-pr...@isocpp.org
In the latter case, you've textually duplicated the return value; statement, which makes it OK for the two occurrences to have different meanings (here, name lookup yielding a member vs. a namespace scope variable). It is not acceptable for a template in two instantiations to have such different meanings.

If the above doesn't convince you, how about this old chestnut:

using U = int;
template<typename T> struct X {
  int i;
  some_kind_of_static_if (is_fooable_v<T>) {
    static int const U;
  }
  auto f() { U * i; return i; }
};
Reply all
Reply to author
Forward
0 new messages