c++ power of integer, template meta programming - c++

I want to make a function which returns a power of integer.
Please read the fmuecke's solution in
power of an integer in c++ .
However, I want to generalize his solution to the arbitrary type T.
Since c++11 has constexpr, I guess this is possible.
Naively, I tried something like,
template<class T, int N>
inline constexpr T pow(const T x){
return pow<N-1>(x) * x;
}
template<class T>
inline constexpr T pow<T, 1>(const T x){
return x;
}
template<class T>
inline constexpr T pow<T, 0>(const T x){
return 1;
}
Actually this approach failed since the partial specialization for function template is not allowed.
And one more question. I heard that it is up to the compiler whether the constexpr function is evaluated in compile time or not.
How do I force it to compute for general type.
I read from somewhere that one of the simplest hack for integral consts is to wrap it in std::integral_const::value.

Solution using recursion:
#include <iostream>
template<class T>
inline constexpr T pow(const T base, unsigned const exponent)
{
// (parentheses not required in next line)
return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
}
int main()
{
std::cout << "pow(2, 4): " << pow(2, 4) << std::endl;
std::cout << "pow(5, 0): " << pow(5, 0) << std::endl;
}
Jeremy W. Murphy suggested/requested a version using exponentiation by squaring:
template<class T>
inline constexpr T pow(const T base, unsigned const exponent)
{
// (parentheses not required in next line)
return (exponent == 0) ? 1 :
(exponent % 2 == 0) ? pow(base, exponent/2)*pow(base, exponent/2) :
base * pow(base, (exponent-1)/2) * pow(base, (exponent-1)/2);
}
"I heard that it is up to the compiler whether the constexpr function is evaluated in compile time or not."
True, AFAIK. The compiler isn't required to do constant-initialization at compile-time, but if you use the result of a constexpr function as a non-type template argument, it has to compute the result at compile-time.
std::cout << std::integral_constant<int, pow(2, 4)>::value << std::endl;
Also see the approach using integral_constant as parameter of pow in Andy Prowl's answer.
Here's how you can enforce compile-time evaluation:
#include <iostream>
#include <type_traits>
// insert a constexpr `pow` implementation, e.g. the one from above
template < typename T, T base, unsigned exponent >
using pow_ = std::integral_constant < T, pow(base, exponent) >;
// macro == error prone, you have been warned
#define POW(BASE, EXPONENT) (pow_ < decltype(BASE), BASE, EXPONENT > :: value)
int main()
{
std::cout << "pow(2, 4): " << pow_<int, 2, 4>::value << std::endl;
std::cout << "pow(2, 4): " << POW(2, 4) << std::endl;
}
Please leave a comment if you downvote so I can improve my answer.

When you find yourself in need of partially specializing a function template (beware, this does not mean that in this case you are in need, as DyP's answer shows), you may either resort to overloading (see the last update at the end of this answer) or, if that's not possible, wrap that function template into a class template, and have a static, non-template member function replace your original function template (and its specializations):
namespace detail
{
template<class T, int N>
struct helper
{
static constexpr T pow(const T x){
return helper<T, N-1>::pow(x) * x;
}
};
template<class T>
struct helper<T, 1> // Unnecessary specialization! (see the edit)
{
static constexpr T pow(const T x){
return x;
}
};
template<class T>
struct helper<T, 0>
{
static constexpr T pow(const T x){
return 1;
}
};
}
Then, you could provide a helper function template that delegates to the specialization of your helper class template:
template<int N, class T>
T constexpr pow(T const x)
{
return detail::helper<T, N>::pow(x);
}
Here is a live example.
EDIT:
Notice, that the specialization for N == 1 is actually not necessary. I kept it in the original text because the purpose of this answer was mainly to show how to workaround the impossibility of partially specializing function templates in general - so I translated the original program piece-by-piece.
As noted by Dyp in the comments, however, this would be enough:
namespace detail
{
template<class T, int N>
struct helper
{
static constexpr T pow(const T x){
return helper<T, N-1>::pow(x) * x;
}
};
template<class T>
struct helper<T, 0>
{
static constexpr T pow(const T x){
return 1;
}
};
}
UPDATE:
As a further remark, please keep in mind that even when you can specialize function templates (e.g. with explicit - not partial - specializations), it is generally not a good idea to do so, because function template specialization does not normally behave as one would expect.
Most of those situations that may seem to ask for function template specialization can actually be achieved through overloading, powered by well-known techniques such as tag dispatching. An example is proposed by Potatoswatter in the comments, pointing out that std::integral_constant could be used in this situation:
template<class T>
inline constexpr T pow(const T x, std::integral_constant<int, 0>){
return 1;
}
template<class T, int N>
inline constexpr T pow(const T x, std::integral_constant<int, N>){
return pow(x, std::integral_constant<int, N-1>()) * x;
}
template<int N, class T>
inline constexpr T pow(const T x)
{
return pow(x, std::integral_constant<int, N>());
}
However, all these guidelines on "how to solve problems that seem to require function template partial specialization" should be taken into consideration when they are really needed. In this concrete case, as DyP showed in his answer, they are not.

Here is a solution with a single function:
template <int N, class T>
constexpr T pow(const T& x)
{
return N > 1 ? x*pow<(N-1)*(N > 1)>(x)
: N < 0 ? T(1)/pow<(-N)*(N < 0)>(x)
: N == 1 ? x
: T(1);
}

Here is a simple solution:
#include<bits/stdc++.h>
using namespace std;
template<int N, int M>
struct Pow
{
enum { res = N * Pow<N,M-1>::res};
};
template<int N>
struct Pow<N,0>
{
enum {res = 1};
};
int main()
{
cout<<Pow<2,3>::res<<"\n";
}

Clean and simple solution here:
#include <cstddef>
template<size_t N, size_t P>
struct pow_constexpr { constexpr static auto value = N * pow_constexpr<N, P-1>::value; };
template<size_t N>
struct pow_constexpr<N, 1> { constexpr static auto value = N; };
template<size_t N>
struct pow_constexpr<N, 0> { constexpr static auto value = 1; };
int main() {
return pow_constexpr<2, 30>::value; // 1073741824
}

Related

Creating a base case for Variadic Template recursion with no template arguments

I'm trying to use recursion with variadic templates. I would like the base case to have zero template arguments. After looking through stackoverflow answers to previous questions, I have found two kinds of responses to this problem:
You should not specialize templates functions. Herb Sutter wrote about that here: http://www.gotw.ca/publications/mill17.htm
You use template <typename = void> or template <typename T = void> . For example, the first answer here: How to write a variadic template recursive function?
I attempted to use the solution (2) in my problem, but received errors. This is a Minimal, Reproducible Example:
#include <iostream>
template<typename = void> // base case
int NumArguments() {
return 0;
}
template<typename FirstArg, typename... RemainingArgs>
int NumArguments() {
return 1 + NumArguments<RemainingArgs...>();
}
class A {
public:
A() {}
};
int main() {
std::cout << NumArguments<A>();
return 0;
}
Compilation in Microsoft Visual C++20 gave the errors:
error C2668: 'NumArguments': ambiguous call to overloaded function
message : could be 'int NumArguments<A,>(void)'
message : or 'int NumArguments<A>(void)'
message : while trying to match the argument list '()'
What does this error message mean? How do I create a zero-argument base case for recursion with variadic templates?
Edit: There were requests in the comments for a more complete description of my problem. The question really is the question title, and not "how do I get my code to work?", but I have not yet gotten my code to compile, so I have decided to share it.
NumArguments is a stand-in for another function ComputeSize that takes as input Args and returns an std::size_t.
template<typename = void>
constexpr std::size_t ComputeSize() {
return 0;
}
template<typename FirstArg, typename... RemainingArgs>
constexpr std::size_t ComputeSize() {
return FuncReturnSize<FirstArg>() + ComputeSize<RemainingArgs...>();
}
The possible list of Args in Args is finite and known prior to compilation. FuncReturnSize is overloaded for each of these Args. For example, two possible "overloads"(?) are
template <typename T>
requires ((requires (T t) { { t.Func()} -> std::same_as<double>; }) || (requires (T t) { { t.Func() } -> std::same_as<std::vector<double>>; }))
constexpr std::size_t FuncReturnSize() {
return 1;
}
template <typename T>
requires requires (T t) { { t.Func() } -> is_std_array_concept<>; }
constexpr std::size_t FuncReturnSize() {
return std::tuple_size_v<decltype(std::declval<T&>().Func())>;
}
The concept is_std_array_concept<> should check if the return value of t.Func() is some size array. I am not yet sure if it works. It is defined by
template<class T>
struct is_std_array : std::false_type {};
template<class T, std::size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {};
template<class T>
struct is_std_array<T const> : is_std_array<T> {};
template<class T>
struct is_std_array<T volatile> : is_std_array<T> {};
template<class T>
struct is_std_array<T volatile const> : is_std_array<T> {};
template<typename T>
concept is_std_array_concept = is_std_array<T>::value;
I want all of this computation to be done at compile-time, so I have defined
template<std::size_t N>
std::size_t CompilerCompute() {
return N;
}
I should now be able to ComputeSize at compile time like so:
CompilerCompute<ComputeSize<Args...>()>()
The error message means exactly what it says, the call is ambiguous.
template<typename = void> // base case
constexpr int NumArguments() {
return 0;
}
This is not a template function that takes 0 arguments, this is a template function that takes one argument that's defaulted (so if the argument isn't specified, it's void). This means that NumArguments<A>() is a perfectly valid call to this function.
But, NumArguments<A>() is also a perfectly valid call to the variadic overload with an empty variadic pack (the NumArguments<A,>() overload listed in the error message).
What sets your case apart from the linked example is that in the linked example, the variadiac overload is templated on ints, not on types, so there's no ambiguity there. I've copied that implementation here:
template<class none = void>
constexpr int f()
{
return 0;
}
template<int First, int... Rest>
constexpr int f()
{
return First + f<Rest...>();
}
int main()
{
f<1, 2, 3>();
return 0;
}
Notice, the second overload of f is a variadic template where each template parameter must be an int value. Calling f<A>() won't match that overload if A is a type, so the ambiguity is avoided.
It's not possible to declare a zero-argument template function, so you're out of luck there. However, you can instead convert this to a class template as class templates can be partially specialized.
template <class ...Args>
struct NumArguments;
template <>
struct NumArguments<> {
static constexpr int value = 0;
};
template <class T, class ...Args>
struct NumArguments<T, Args...> {
static constexpr int value = 1 + NumArguments<Args...>::value;
};
This specific implementation could, of course, by simplified to use sizeof..., but the OP has indicated that their real use case is more complicated.
Here's another solution (without specialization), which uses a C++20 requires clause to resolve the ambiguity:
template <typename... Args> requires (sizeof...(Args) == 0)
constexpr int NumArguments() {
return 0;
}
template<typename FirstArg, typename... RemainingArgs>
constexpr int NumArguments() {
return 1 + NumArguments<RemainingArgs...>();
}
Example:
int main() {
std::cout << NumArguments<int>() << std::endl;
std::cout << NumArguments() << std::endl;
std::cout << NumArguments<float, int, double, char>() << std::endl;
return 0;
}
1
0
4
EDIT:
My old suggestion using concepts was incorrect. There's a good post here on using concepts and parameter packs.
You should guarantee the end of your variadic template without overloading the function.
A solution compiling with c++ standard 17 (in Microsoft Visual /std:c++17) is the following:
#include <iostream>
//Remove or comment base case!
template<typename FirstArg=void, typename... RemainingArgs>
constexpr int NumArguments() {
if (sizeof...(RemainingArgs) == 0)
return 1;
else
return (NumArguments<FirstArg>() + NumArguments<RemainingArgs...>());
}
class A {
public:
A() {}
};
int main() {
std::cout << NumArguments<A>();
return 0;
}
Sadly I couldn't quite get a is_std_array concept to work, but in terms of your NumArguments<T...>(), it could be done with fold expression pretty easily:
template<typename ...T>
int NumArguments()
{
return (FuncReturnSize<T>() + ...);
}
The fold expression here will be expanded like:
return (((FuncReturnSize<T1>() + FuncReturnSize<T2>()) + FuncReturnSize<T3>()) + FuncReturnSize<T4>)
Demo
Here I specialized std::integral and std::floating_point version of FuncReturnSize(), and any other types would just return sizeof(T). And you should be able to easily specialize other types with a good concept defined.
Note I also made FuncReturnSize()s consteval.

How can I deduce a template parameter type in C++11?

I'm attempting to write a function that forces constexpr evaluation via. a template. I wrote this, but it works only for int (beware, will give recursion depth errors with GCC):
#include <iostream>
template<int val>
constexpr int force_constexpr() { return val; }
constexpr int triangle(int n)
{
return n ? n + triangle(n - 1) : 0;
}
int main(void)
{
std::cout << force_constexpr<triangle(0x200)>() << '\n';
}
Note that this is for demonstration purposes only; I know that the triangle number can be calculated with (n+1)*n/2.
Then I attempted to write a generic function, however, that doesn't work as well. This is a plain error (not surprising, as it uses T before T is defined):
template<T val, typename T = decltype(val)>
constexpr T force_constexpr() { return val; }
as is this (which obviously won't work; it's a nested template):
template<typename T>
template<T val>
constexpr T force_constexpr() { return val; }
and this requires the type of the argument to be passed:
template<typename T, T val>
constexpr T force_constexpr() { return val; }
How can I do this without passing the type as a parameter to the template? Or, in other words, how can I deduce a template parameter type?
I'm looking for a C++11 solution but solutions for other standards are welcome.
You're looking for auto template parameters, in C++17:
#include <iostream>
template<auto T>
auto *singleton()
{
static const decltype(T) solo{T};
return &solo;
}
int main()
{
const int *p=singleton<42>();
std::cout << "The meaning of life: " << *p << std::endl;
return 0;
}
Specify the template parameter as auto, and use decltype to deduce its type.
I do not believe that this is possible before C++17, since this is precisely the use case for which auto template parameters were added to the standard. Couldn't do this, conceptually, before then.
C++17 introduces auto as non type template parameter:
template <auto val>
constexpr auto force_constexpr() { return val; }
Before, you have indeed blocked with
template<typename T, T val>
constexpr T force_constexpr() { return val; }
You can introduce MACRO to simplify usage:
#define AUTO(v) decltype(v), (v)
And then
std::cout << force_constexpr<AUTO(triangle(0x200))>() << '\n';

Use one namespace or another in function of a template parameter

I want to use the implementation of std::pow (from cmath) in some cases, and in other cases, I want to use myspace::pow.
namespace myspace
{
template <typename T>
T pow(T val, unsigned exp)
{
if (exp == 0) return 1;
return val*pow(val,exp-1);
}
}
The different cases are determined by a template parameter.
template <typename T>
void myFunction()
{
auto val = pow(2.1,3);
/* ... */
}
If T == double, I want val to be calculated with std::pow. If T == mydouble, I want val to be calculated with myspace::pow. Now, I have a lot of lines like auto val = pow(2.1,3);, and I would like to avoid to check for the type of T for each line of code.
struct mydouble { /* ... */ };
myFunction<double>(); // uses std::pow
myFunction<mydouble>(); // uses myspace::pow
I've been breaking my head over this, but I can't find a solution. Any suggestions?
There are several solutions I could suggest.
Class Dispatcher (C++11)
Just implement a functor which picks the correct implementation in accordance with its templated type:
template <typename T>
struct PowerAdapter {
auto operator()(const T& arg, const T& exp) const {
return std::pow(arg, exp);
}
};
template <>
struct PowerAdapter<myspace::MyDouble> {
auto operator()(const myspace::MyDouble& arg, unsigned exp) const {
return myspace::pow(arg, exp);
}
};
And you can use it as follows:
template <typename T>
void myFunction(const T& t) {
using Pow = PowerAdapter<T>;
auto val = Pow{}(t, t);
// ...
}
Complete Code Example
Argument-Dependent Lookup (C++98)
If your class MyDouble is in the same namespace of your pow then you can just use this C++ rule:
[...] function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.
So the code:
template <typename T>
void myFunction(const T& t) {
pow(t, 12);
}
will select the proper pow in accordance with the namespace of T.
Note that, in case of double, you want to select the pow from math.h in the global namespace (unqualified name lookup).
Complete Code Example
I personally don't like this approach because it hides the selection mechanism and it's more difficult to extend.
if constexpr (C++17)
You can pick a proper branch at compile time.
Wrap your select logic into a proper function (or functor). Something like:
template <typename T, typename U>
auto PowerAdapter(const T& val, const U& exp) {
if constexpr (std::is_same_v<T, myspace::MyDouble>) {
return myspace::pow(val, exp);
} else {
return std::pow(val, exp);
}
}
Complete Code Example
Using Argument-dependent lookup you can achieve this easily
namespace ns
{
template <typename T>
auto pow(T val, unsigned exp)
{
using std::pow;
std::cout << __FUNCTION__ << '\n';
return pow(val, exp);
}
}
struct mydouble
{
double d;
};
mydouble pow(mydouble val, unsigned exp)
{
std::cout << __FUNCTION__ << '\n';
return val;
}
int main()
{
ns::pow(mydouble{ 3.14 }, 2); // runs pow
ns::pow(4, 2); // runs std::pow
}

Could you please explain below code ? It compiles fine. Its related to check whether given class is base of another class [duplicate]

I want to get into more template meta-programming. I know that SFINAE stands for "substitution failure is not an error." But can someone show me a good use for SFINAE?
I like using SFINAE to check boolean conditions.
template<int I> void div(char(*)[I % 2 == 0] = 0) {
/* this is taken when I is even */
}
template<int I> void div(char(*)[I % 2 == 1] = 0) {
/* this is taken when I is odd */
}
It can be quite useful. For example, i used it to check whether an initializer list collected using operator comma is no longer than a fixed size
template<int N>
struct Vector {
template<int M>
Vector(MyInitList<M> const& i, char(*)[M <= N] = 0) { /* ... */ }
}
The list is only accepted when M is smaller than N, which means that the initializer list has not too many elements.
The syntax char(*)[C] means: Pointer to an array with element type char and size C. If C is false (0 here), then we get the invalid type char(*)[0], pointer to a zero sized array: SFINAE makes it so that the template will be ignored then.
Expressed with boost::enable_if, that looks like this
template<int N>
struct Vector {
template<int M>
Vector(MyInitList<M> const& i,
typename enable_if_c<(M <= N)>::type* = 0) { /* ... */ }
}
In practice, i often find the ability to check conditions a useful ability.
Heres one example (from here):
template<typename T>
class IsClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
// Will be chosen if T is anything except a class.
template<typename C> static Two test(...);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};
When IsClassT<int>::Yes is evaluated, 0 cannot be converted to int int::* because int is not a class, so it can't have a member pointer. If SFINAE didn't exist, then you would get a compiler error, something like '0 cannot be converted to member pointer for non-class type int'. Instead, it just uses the ... form which returns Two, and thus evaluates to false, int is not a class type.
In C++11 SFINAE tests have become much prettier. Here are a few examples of common uses:
Pick a function overload depending on traits
template<typename T>
std::enable_if_t<std::is_integral<T>::value> f(T t){
//integral version
}
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value> f(T t){
//floating point version
}
Using a so called type sink idiom you can do pretty arbitrary tests on a type like checking if it has a member and if that member is of a certain type
//this goes in some header so you can use it everywhere
template<typename T>
struct TypeSink{
using Type = void;
};
template<typename T>
using TypeSinkT = typename TypeSink<T>::Type;
//use case
template<typename T, typename=void>
struct HasBarOfTypeInt : std::false_type{};
template<typename T>
struct HasBarOfTypeInt<T, TypeSinkT<decltype(std::declval<T&>().*(&T::bar))>> :
std::is_same<typename std::decay<decltype(std::declval<T&>().*(&T::bar))>::type,int>{};
struct S{
int bar;
};
struct K{
};
template<typename T, typename = TypeSinkT<decltype(&T::bar)>>
void print(T){
std::cout << "has bar" << std::endl;
}
void print(...){
std::cout << "no bar" << std::endl;
}
int main(){
print(S{});
print(K{});
std::cout << "bar is int: " << HasBarOfTypeInt<S>::value << std::endl;
}
Here is a live example: http://ideone.com/dHhyHE
I also recently wrote a whole section on SFINAE and tag dispatch in my blog (shameless plug but relevant) http://metaporky.blogspot.de/2014/08/part-7-static-dispatch-function.html
Note as of C++14 there is a std::void_t which is essentially the same as my TypeSink here.
Boost's enable_if library offers a nice clean interface for using SFINAE. One of my favorite usage examples is in the Boost.Iterator library. SFINAE is used to enable iterator type conversions.
Here's another (late) SFINAE example, based on Greg Rogers's answer:
template<typename T>
class IsClassT {
template<typename C> static bool test(int C::*) {return true;}
template<typename C> static bool test(...) {return false;}
public:
static bool value;
};
template<typename T>
bool IsClassT<T>::value=IsClassT<T>::test<T>(0);
In this way, you can check the value's value to see whether T is a class or not:
int main(void) {
std::cout << IsClassT<std::string>::value << std::endl; // true
std::cout << IsClassT<int>::value << std::endl; // false
return 0;
}
Examples provided by other answers seems to me more complicated than needed.
Here is the slightly easier to understand example from cppreference :
#include <iostream>
// this overload is always in the set of overloads
// ellipsis parameter has the lowest ranking for overload resolution
void test(...)
{
std::cout << "Catch-all overload called\n";
}
// this overload is added to the set of overloads if
// C is a reference-to-class type and F is a pointer to member function of C
template <class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void())
{
std::cout << "Reference overload called\n";
}
// this overload is added to the set of overloads if
// C is a pointer-to-class type and F is a pointer to member function of C
template <class C, class F>
auto test(C c, F f) -> decltype((void)((c->*f)()), void())
{
std::cout << "Pointer overload called\n";
}
struct X { void f() {} };
int main(){
X x;
test( x, &X::f);
test(&x, &X::f);
test(42, 1337);
}
Output:
Reference overload called
Pointer overload called
Catch-all overload called
As you can see, in the third call of test, substitution fails without errors.
C++17 will probably provide a generic means to query for features. See N4502 for details, but as a self-contained example consider the following.
This part is the constant part, put it in a header.
// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf.
template <typename...>
using void_t = void;
// Primary template handles all types not supporting the operation.
template <typename, template <typename> class, typename = void_t<>>
struct detect : std::false_type {};
// Specialization recognizes/validates only types supporting the archetype.
template <typename T, template <typename> class Op>
struct detect<T, Op, void_t<Op<T>>> : std::true_type {};
The following example, taken from N4502, shows the usage:
// Archetypal expression for assignment operation.
template <typename T>
using assign_t = decltype(std::declval<T&>() = std::declval<T const &>())
// Trait corresponding to that archetype.
template <typename T>
using is_assignable = detect<T, assign_t>;
Compared to the other implementations, this one is fairly simple: a reduced set of tools (void_t and detect) suffices. Besides, it was reported (see N4502) that it is measurably more efficient (compile-time and compiler memory consumption) than previous approaches.
Here is a live example, which includes portability tweaks for GCC pre 5.1.
Here is one good article of SFINAE: An introduction to C++'s SFINAE concept: compile-time introspection of a class member.
Summary it as following:
/*
The compiler will try this overload since it's less generic than the variadic.
T will be replace by int which gives us void f(const int& t, int::iterator* b = nullptr);
int doesn't have an iterator sub-type, but the compiler doesn't throw a bunch of errors.
It simply tries the next overload.
*/
template <typename T> void f(const T& t, typename T::iterator* it = nullptr) { }
// The sink-hole.
void f(...) { }
f(1); // Calls void f(...) { }
template<bool B, class T = void> // Default template version.
struct enable_if {}; // This struct doesn't define "type" and the substitution will fail if you try to access it.
template<class T> // A specialisation used if the expression is true.
struct enable_if<true, T> { typedef T type; }; // This struct do have a "type" and won't fail on access.
template <class T> typename enable_if<hasSerialize<T>::value, std::string>::type serialize(const T& obj)
{
return obj.serialize();
}
template <class T> typename enable_if<!hasSerialize<T>::value, std::string>::type serialize(const T& obj)
{
return to_string(obj);
}
declval is an utility that gives you a "fake reference" to an object of a type that couldn't be easily construct. declval is really handy for our SFINAE constructions.
struct Default {
int foo() const {return 1;}
};
struct NonDefault {
NonDefault(const NonDefault&) {}
int foo() const {return 1;}
};
int main()
{
decltype(Default().foo()) n1 = 1; // int n1
// decltype(NonDefault().foo()) n2 = n1; // error: no default constructor
decltype(std::declval<NonDefault>().foo()) n2 = n1; // int n2
std::cout << "n2 = " << n2 << '\n';
}
The following code uses SFINAE to let compiler select an overload based on whether a type has certain method or not:
#include <iostream>
template<typename T>
void do_something(const T& value, decltype(value.get_int()) = 0) {
std::cout << "Int: " << value.get_int() << std::endl;
}
template<typename T>
void do_something(const T& value, decltype(value.get_float()) = 0) {
std::cout << "Float: " << value.get_float() << std::endl;
}
struct FloatItem {
float get_float() const {
return 1.0f;
}
};
struct IntItem {
int get_int() const {
return -1;
}
};
struct UniversalItem : public IntItem, public FloatItem {};
int main() {
do_something(FloatItem{});
do_something(IntItem{});
// the following fails because template substitution
// leads to ambiguity
// do_something(UniversalItem{});
return 0;
}
Output:
Float: 1
Int: -1
Here, I am using template function overloading (not directly SFINAE) to determine whether a pointer is a function or member class pointer: (Is possible to fix the iostream cout/cerr member function pointers being printed as 1 or true?)
https://godbolt.org/z/c2NmzR
#include<iostream>
template<typename Return, typename... Args>
constexpr bool is_function_pointer(Return(*pointer)(Args...)) {
return true;
}
template<typename Return, typename ClassType, typename... Args>
constexpr bool is_function_pointer(Return(ClassType::*pointer)(Args...)) {
return true;
}
template<typename... Args>
constexpr bool is_function_pointer(Args...) {
return false;
}
struct test_debugger { void var() {} };
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}
int main(void) {
int* var;
std::cout << std::boolalpha;
std::cout << "0. " << is_function_pointer(var) << std::endl;
std::cout << "1. " << is_function_pointer(fun_void_void) << std::endl;
std::cout << "2. " << is_function_pointer(fun_void_double) << std::endl;
std::cout << "3. " << is_function_pointer(fun_double_double) << std::endl;
std::cout << "4. " << is_function_pointer(&test_debugger::var) << std::endl;
return 0;
}
Prints
0. false
1. true
2. true
3. true
4. true
As the code is, it could (depending on the compiler "good" will) generate a run time call to a function which will return true or false. If you would like to force the is_function_pointer(var) to evaluate at compile type (no function calls performed at run time), you can use the constexpr variable trick:
constexpr bool ispointer = is_function_pointer(var);
std::cout << "ispointer " << ispointer << std::endl;
By the C++ standard, all constexpr variables are guaranteed to be evaluated at compile time (Computing length of a C string at compile time. Is this really a constexpr?).

float or double in templated code

The following example might seem nonsensical, but it's part of a larger high-performance code where the presented technique makes sense. I mention this just in case someone should suspect an XY question - it's most probably not.
I have a function with templated/compile-time operand:
template <int M>
int mul(int x){
return M * x;
}
Now I want to do the same for double, what is - of course - not allowed:
template <double M> // you can't do that!
int mul(double x){
return M * x;
}
So to still put in the double at compile time, I only see the following solution:
// create my constants
struct SevenPointFive{
static constexpr double VAL = 7.5;
}
struct ThreePointOne{
static constexpr double VAL = 3.1;
}
// modified function
template <class M>
int mul(double x){
return M::VAL * x;
}
// call it
double a = mul<SevenPointFive>(3.2);
double b = mul<ThreePointOne>(a);
Is there a better solution for the problem to somehow pass a double constant in a template parameter, without creating a struct for each value?
(I'm interested in a solution which actually uses double/float, not a hack with using two ints to create a rational number or fixed point ideas such as y = 0.01 * M * x.)
In C++11, it is not necessary to use templates at all. Simply use constexpr (generalised constant expressions) in a different way than you are.
#include <iostream>
constexpr double mul(double x, double y)
{
return x*y;
}
int main()
{
std::cout << mul(2.3, 3.4) << '\n';
double x;
std::cin >> x; // to demonstrate constexpr works with variables
std::cout << mul(2.3, x) << '\n';
}
Although I say templates aren't necessary (which they aren't in the example given) these can be templated if needed
template <class T> constexpr T mul(T x, T y) {return x*y;}
or (if you want to use the function for types that are better passed by const reference)
template <class T> constexpr T mul(const T &x, const T &y) {return x*y;}
You can conveniently pass floating point values in template parameters using user-defined literals.
Just write a literal that creates your envelope class. Then you can write something like
mul<decltype(3.7_c)>(7)
Or even better, have your function take the argument by value so you can write
mul(3.7_c, 7)
the compiler will make that just as efficient.
Below's an example of code that does this:
#include <iostream>
template <int Value, char...>
struct ParseNumeratorImpl {
static constexpr int value = Value;
};
template <int Value, char First, char... Rest>
struct ParseNumeratorImpl<Value, First, Rest...> {
static constexpr int value =
(First == '.')
? ParseNumeratorImpl<Value, Rest...>::value
: ParseNumeratorImpl<10 * Value + (First - '0'), Rest...>::value;
};
template <char... Chars>
struct ParseNumerator {
static constexpr int value = ParseNumeratorImpl<0, Chars...>::value;
};
template <int Value, bool, char...>
struct ParseDenominatorImpl {
static constexpr int value = Value;
};
template <int Value, bool RightOfDecimalPoint, char First, char... Rest>
struct ParseDenominatorImpl<Value, RightOfDecimalPoint, First, Rest...> {
static constexpr int value =
(First == '.' && sizeof...(Rest) > 0)
? ParseDenominatorImpl<1, true, Rest...>::value
: RightOfDecimalPoint
? ParseDenominatorImpl<Value * 10, true, Rest...>::value
: ParseDenominatorImpl<1, false, Rest...>::value;
};
template <char... Chars>
using ParseDenominator = ParseDenominatorImpl<1, false, Chars...>;
template <int Num, int Denom>
struct FloatingPointNumber {
static constexpr float float_value =
static_cast<float>(Num) / static_cast<float>(Denom);
static constexpr double double_value =
static_cast<double>(Num) / static_cast<double>(Denom);
constexpr operator double() { return double_value; }
};
template <int Num, int Denom>
FloatingPointNumber<-Num, Denom> operator-(FloatingPointNumber<Num, Denom>) {
return {};
}
template <char... Chars>
constexpr auto operator"" _c() {
return FloatingPointNumber<ParseNumerator<Chars...>::value,
ParseDenominator<Chars...>::value>{};
}
template <class Val>
int mul(double x) {
return Val::double_value * x;
}
template <class Val>
int mul(Val v, double x) {
return v * x;
}
int main() {
std::cout << mul<decltype(3.79_c)>(77) << "\n";
std::cout << mul(3.79_c, 77) << "\n";
return 0;
}
constexpr double make_double( int64_t v, int64_t man );
write a function that makes a double from a base and mantissa. This can represent every non-special double.
Then write:
template<int64_t v, int64_t man>
struct double_constant;
using the above make_double and various constexpr access methods.
You can even write base and exponent extracting constexpr functions I suspect. Add a macro to remove DRY, or use a variable.
Another approach is:
const double pi=3.14;//...
template<double const* v>
struct dval{
operator double()const{return *v;}
};
template<class X>
double mul(double d){
return d*X{};
}
double(*f)(double)=mul<dval<&pi>>;
which requires a variable to point to, but is less obtuse.
If you don't want to create type envelopes for each double/float constant used, then you can create a mapping between integer and double constants. Such mapping can be implemented e.g. as follows:
#include <string>
#include <sstream>
template<int index> double getValue()
{
std::stringstream ss("Not implemented for index ");
ss << index;
throw std::exception(ss.str());
}
template<> double getValue<0>() { return 3.6; }
template<> double getValue<1>() { return 7.77; }
template<int index> double multiply(double x)
{
return getValue<index>() * x;
}
Alternative options to implement the mapping are via a function which does switch-case on the input integer parameter and returns a float/double, or indexing to an array of constants, but both these alternatives would require constexpr for them to happen on compile-time, while some compilers still do not support constexpr: constexpr not compiling in VC2013