[dune-functions] How to check that a function is scalar (or vector valued)

Christian Engwer christian.engwer at uni-muenster.de
Wed Apr 1 22:10:26 CEST 2015


Hi Carsten,

> I'm not sure if I understand the problem correctly.

you guessed right. I finally came up with a different solution... atm
it is sufficient to destinguish between scalar and others; other are
assumed to be vector valued.

The scalar case is now checked by checking
std::is_convertible<typename FieldTraits< Range >::field_type, Range>::value
which tries to convert the Range type to the corresponding FieldType.

It is not exactly what I asked for, but it actually checks exactly
what I want to know ;-)

Besides this I like your approach of using a free function for size,
even if I don't need it anymore in this case. In any case I think we
should use much more free function, also the setTime member in
dune-pdelab could in many situations easier be integrated if it is a
free function.

Ciao
Christian

>
> Am 01.04.2015 um 10:10 schrieb Christian Engwer:
> > Dear all,
> >
> > I'm currently struggling with a particular problem. I tried to get the
> > dune-pdelab interpolate work with new-style dune-functions
> > functions. The particular problem for me is now, that I have to deduce
> > the range type of my function. In particular I have check that the
> > returned value is either is_scalar (we would like to be able to return
> > double instead of FieldVector<double,1>) or that the size() is a
> > constexpr with value 1. One particular problem is that the size method
> > is not static, thus we can not easily check the value without an
> > object... It seems my C++ skills are diminishing, so perhaps one you
> > guys can enlighten me ;-)
>
> Do you explicitly want to call the size() method? One can get an
> "object" by doing a static_cast of nullptr to the desired type
> (declval can't be used in a constexpr) and this even works
> for simple types. But in view of this gcc error message it
> seems that anything like this cannot work in general:
>
>   getsize.cc: In function ‘int main()’:
>   getsize.cc:32:29: error: call to non-constexpr function ‘constexpr int Foo<i>::size() const [with int i = 3]’
>        auto bar = Foo<foo.size()+1>();
>                                ^
>   getsize.cc:16:19: note: ‘constexpr int Foo<i>::size() const [with int i = 3]’ is not usable as a constexpr function because:
>        constexpr int size() const
>                      ^
>   getsize.cc:16:19: error: enclosing class of constexpr non-static member function ‘constexpr int Foo<i>::size() const [with int i = 3]’ is not a literal type
>   getsize.cc:4:7: note: ‘Foo<3>’ is not literal because:
>    class Foo
>          ^
>   getsize.cc:4:7: note:   ‘Foo<3>’ is not an aggregate, does not have a trivial default constructor, and has no constexpr constructor that is not a copy or move constructor
>   getsize.cc:32:29: error: call to non-constexpr function ‘constexpr int Foo<i>::size() const [with int i = 3]’
>        auto bar = Foo<foo.size()+1>();
>
> > I tried to come up with a type trait to check for the value of size,
> > but the non-static thing was always the show-stopper for me.
>
> One way to get around would be to have a free size() method
> which has to be specialized, see attached example. This is
> not that strange: As far as I know there is even an accepted
> proposal for std::size() in the C++17 draft.
>
> Best,
> Carsten
>
>

> #include <iostream>
> #include <array>
>
>
> template<class T, size_t i>
> constexpr int size(const std::array<T, i>&)
> {
>     return i;
> }
>
> template<class T,
>     typename std::enable_if< std::is_scalar<T>::value, int>::type = 0>
> constexpr int size(const T&)
> {
>     return 1;
> }
>
>
> template <int i>
> using Int = typename std::integral_constant<int,i>;
>
> int main()
> {
>     std::cout << Int<size(std::array<double,3>())>() << std::endl;
>     std::cout << Int<size(1.3)>() << std::endl;
>     std::cout << Int<size(3)>() << std::endl;
>
>     return 0;
> }




> _______________________________________________
> dune-functions mailing list
> dune-functions at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune-functions


--
Prof. Dr. Christian Engwer
Institut für Numerische und Angewandte Mathematik
Fachbereich Mathematik und Informatik der Universität Münster
Einsteinstrasse 62
48149 Münster

E-Mail	christian.engwer at uni-muenster.de
Telefon	+49 251 83-35067
FAX		+49 251 83-32729




More information about the dune-functions mailing list