Reference documentation for deal.II version 9.0.0
Related Functions | List of all members
EnableIfScalar< T > Struct Template Reference

#include <deal.II/base/template_constraints.h>

Related Functions

(Note that these are not member functions.)

template<int dim, typename Number , typename OtherNumber >
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator* (const OtherNumber factor, const Point< dim, Number > &p)
 
template<int rank_, int dim, typename Number , typename OtherNumber >
SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator* (const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
 
template<int rank_, int dim, typename Number , typename OtherNumber >
SymmetricTensor< rank_, dim, typename ProductType< OtherNumber, typename EnableIfScalar< Number >::type >::type > operator* (const Number &factor, const SymmetricTensor< rank_, dim, OtherNumber > &t)
 

Detailed Description

template<typename T>
struct EnableIfScalar< T >

This class provides a local typedef type that is equal to the template argument but only if the template argument corresponds to a scalar type (i.e., one of the floating point types, signed or unsigned integer, or a complex number). If the template type T is not a scalar, then no class EnableIfScalar<T> is declared and, consequently, no local typedef is available.

The purpose of the class is to disable certain template functions if one of the arguments is not a scalar number. By way of (nonsensical) example, consider the following function:

template <typename T>
T multiply (const T t1, const T t2) { return t1*t2; }

This function can be called with any two arguments of the same type T. This includes arguments for which this clearly makes no sense. Consequently, one may want to restrict the function to only scalars, and this can be written as

template <typename T>
multiply (const T t1, const T t2) { return t1*t2; }

At a place where you call the function, the compiler will deduce the type T from the arguments. For example, in

multiply(1.234, 2.345);

it will deduce T to be double, and because EnableIfScalar<double>::type equals double, the compiler will instantiate a function double multiply(const double, const double) from the template above. On the other hand, in a context like

std::vector<char> v1, v2;
multiply(v1, v2);

the compiler will deduce T to be std::vector<char> but because EnableIfScalar<std::vector<char>>::type does not exist the compiler does not consider the template for instantiation. This technique is called "Substitution Failure is not an Error (SFINAE)". It makes sure that the template function can not even be called, rather than leading to a later error about the fact that the operation t1*t2 is not defined (or may lead to some nonsensical result). It also allows the declaration of overloads of a function such as multiply for different types of arguments, without resulting in ambiguous call errors by the compiler.

Author
Wolfgang Bangerth, Matthias Maier, 2015 - 2017

Definition at line 25 of file complex_overloads.h.

Friends And Related Function Documentation

◆ operator*() [1/3]

template<int dim, typename Number , typename OtherNumber >
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator* ( const OtherNumber  factor,
const Point< dim, Number > &  p 
)
related

Global operator scaling a point vector by a scalar.

Definition at line 537 of file point.h.

◆ operator*() [2/3]

template<int rank_, int dim, typename Number , typename OtherNumber >
SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator* ( const SymmetricTensor< rank_, dim, Number > &  t,
const OtherNumber &  factor 
)
related

Multiplication of a symmetric tensor with a scalar number from the right.

The purpose of this operator is to enable only multiplication of a tensor by a scalar number (i.e., a floating point number, a complex floating point number, etc.). The function is written in a way that only allows the compiler to consider the function if the second argument is indeed a scalar number – in other words, OtherNumber will not match, for example std::vector<double> as the product of a tensor and a vector clearly would make no sense. The mechanism by which the compiler is prohibited of considering this operator for multiplication with non-scalar types are explained in the documentation of the EnableIfScalar class.

The return type of the function is chosen so that it matches the types of both the tensor and the scalar argument. For example, if you multiply a SymmetricTensor<2,dim,double> by std::complex<double>, then the result will be a SymmetricTensor<2,dim,std::complex<double>>. In other words, the type with which the returned tensor stores its components equals the type you would get if you multiplied an individual component of the input tensor by the scalar factor.

Definition at line 3557 of file symmetric_tensor.h.

◆ operator*() [3/3]

template<int rank_, int dim, typename Number , typename OtherNumber >
SymmetricTensor< rank_, dim, typename ProductType< OtherNumber, typename EnableIfScalar< Number >::type >::type > operator* ( const Number &  factor,
const SymmetricTensor< rank_, dim, OtherNumber > &  t 
)
related

Multiplication of a symmetric tensor with a scalar number from the left. See the discussion with the operator with switched arguments for more information about template arguments and the return type.

Definition at line 3593 of file symmetric_tensor.h.


The documentation for this struct was generated from the following files: