breakpoint in template for specific template parameter - c++

What if i want to set breakpoint into constructor with condition if I == 10?
template < typename T, int I >
class C
{
public:
C<T, I>() { cout << I << endl; }
};

If conditional break point does not work try
template < typename T, int I >
class C
{
public:
C()
{
if(I == 10)
{
* int a= 0; //or try __debugbreak();
}
cout << I << endl;
}
};
EDIT
To break on specific class you may use std::is_same<T, U>::value(or boost analogue) in condition

Related

Metaprogramming - power-like function

I want to define template which would behave similar to power function a^n
a^n = -1 where a < 0 or n < 0
a^0 = 0 (so not exactly as std::pow)
otherwise std::pow
I have a problem defining the condition for point 1 - I assume this will be a combination of enable_if and some defined constexpr checking whether integer is negative.
What I wrote for the 1. point (commented out below) probably does not make sense as it do not compile. I am only starting with metaprogramming, to be honest I do not quite understand it. I would much appreciate if you could provide explanation and/or some resources you found helpful while getting into the topic.
#include <iostream>
#include <cmath>
// std::pow
template <int a, int n>
struct hc {
enum { v = a * hc<a, n - 1>::v };
};
// to break recursion from getting to a^0=0
template <int a>
struct hc<a, 1> {
enum { v = a };
};
// a^0 = 0
template <int a>
struct hc<a, 0> {
enum { v = 0 };
};
// a^n=-1 for negative a or n
/*
template <int i>
constexpr bool is_negative = i < 0;
// a ^ n = -1, where a < 0 or n < 0
template <int a, int n,
typename std::enable_if<is_negative<a> || is_negative<n>>::type>
struct hc {
enum { v = -1 };
};
*/
int main() {
// a^0=0
std::cout << hc<0, 0>::v << " -> 0^0=0\n";
std::cout << hc<3, 0>::v << " -> 3^0=0\n";
// a^n=std::pow
std::cout << hc<1, 1>::v << " -> 1^1=" << std::pow(1, 1) << '\n';
std::cout << hc<2, 2>::v << " -> 2^2=" << std::pow(2, 2) << '\n';
std::cout << hc<0, 2>::v << " -> 0^2=" << std::pow(0, 2) << '\n';
std::cout << hc<3, 2>::v << " -> 3^2=" << std::pow(3, 2) << '\n';
std::cout << hc<3, 7>::v << " -> 3^7=" << std::pow(3, 7) << '\n';
// a^n=-1 for negative a or n
std::cout << hc<-3, 7>::v << " -> -3^7=-1\n";
std::cout << hc<3, -7>::v << " -> 3^-7=-1\n";
std::cout << hc<0, -7>::v << " -> 0^7=-1\n";
std::cout << hc<-3, 0>::v << " -> -3^0=-1\n";
}
There are several ways
Simpler IMO, would be constexpr function
constexpr int hc_impl(int a, int n)
{
if (a < 0 || n < 0) return -1;
if (n == 0) return 0;
int res = 1;
for (int i = 0; i != n; ++n) {
res *= a;
}
return res;
};
template <int a, int n>
struct hc
{
constexpr int v = hc_impl(a, n);
};
The old way with struct, you might add an extra parameter for dispatch, something like:
template <int a, int n, bool b = (a < 0 || n < 0)>
struct hc;
template <int a, int n>
struct hc<a, n, true> {
enum { v = -1 };
};
template <int a>
struct hc<a, 1, true> {
enum { v = -1 };
};
template <int a>
struct hc<a, 0, true> {
enum { v = -1 };
};
template <int a, int n>
struct hc<a, n, false> {
enum { v = a * hc<a, n - 1>::v };
};
// to break recursion from getting to a^0=0
template <int a>
struct hc<a, 1, false> {
enum { v = a };
};
// a^0 = 0
template <int a>
struct hc<a, 0, false> {
enum { v = 0 };
};
This is how I would do it using template constexpr:
template<int a, int n>
constexpr int pow()
{
if ((a < 0) || (n < 0)) return -1;
if (n == 0) return 0;
int result = 1;
for (int i = 0; i < n; i++) result *= a;
return result;
}
int main()
{
static_assert(pow<0,0>() == 0);
static_assert(pow<2, 0>() == 0);
static_assert(pow<-1, 0>() == -1);
static_assert(pow<1, -1>() == -1);
static_assert(pow<2, 3>() == 8);
}
Your partial specialization syntax for the last case is incorrect: you should have something inside <> after template<.....> struct hn.
So, something like this will almost work:
// a ^ n = -1, where a < 0 or n < 0
template <int a, int n,
typename std::enable_if<is_negative<a> || is_negative<n>>::type>
struct hc<a, n> {
enum { v = -1 };
};
enable_if::type is a type which you have to put into a position where it can be SFINAE'd, not just somewhere inside template<>. You typically put it either inside a function signature or inside a partial template specialization.
Like this:
// You have to change your general case definition.
// std::pow
template<int a, int n, typename /*DummyUnusedType*/ = void>
struct hc {
enum { v = a * hc<a, n - 1>::v };
};
// ... your existing definitions here ...
// a ^ n = -1, where a < 0 or n < 0
template <int a, int n>
struct hc<a, n, typename std::enable_if<is_negative<a> || is_negative<n>>::type> {
enum { v = -1 };
};
You actually don't even need is_negative and typename:
struct hc<a, n, std::enable_if_t<(a < 0 || n < 0)>> { // Parens are optional
The only remaining problem is that your <a, 0> case intersects with this one for negative as. You can restrict it for non-negative as using the same trick.
In general, though, constexpr function are superior, as suggested by other answers.

Function specialization to access struct members with getter using enum

I have an enum and a struct
enum STORE_ENUM { A_DATA, B_DATA, C_DATA, D_DATA };
struct Store {
int a;
char b;
long c;
bool d;
}
and I want to access its members with a specialized get function that basically looks like this
T get(STORE_ENUM,store s);
and it returns the appropriate type and hopefully statically type checks.
is this possible in C++?
Yes it's possible. The boost PFR library allows something very similar to how you've envisaged it, e.g.:
auto& x = boost::pfr::get<B_DATA>(s);
See the tutorial here.
With C++17, you can do the following
#include <iostream>
enum struct STORE_ENUM { A_DATA, B_DATA, C_DATA, D_DATA };
struct Store {
int a;
char b;
long c;
bool d;
};
template<STORE_ENUM storeEnum>
auto get(Store const & s){
if constexpr (storeEnum == STORE_ENUM::A_DATA) return s.a;
if constexpr (storeEnum == STORE_ENUM::B_DATA) return s.b;
if constexpr (storeEnum == STORE_ENUM::C_DATA) return s.c;
if constexpr (storeEnum == STORE_ENUM::D_DATA) return s.d;
}
int main(){
auto store = Store{ 0, 'a', 4l, true};
std::cout << get<STORE_ENUM::A_DATA>( store) << "\n";
std::cout << get<STORE_ENUM::B_DATA>( store) << "\n";
std::cout << get<STORE_ENUM::C_DATA>( store) << "\n";
std::cout << get<STORE_ENUM::D_DATA>( store) << "\n";
}
See https://godbolt.org/z/1vffh3
In my solution, we don't need enums. It uses templates.
#include <iostream>
#include <type_traits>
struct Store
{
int a;
char b;
long c;
bool d;
Store() //Default constructor
{
a = 0;
b = 0;
c = 0;
d = false;
}
Store(int a, char b, long c, bool d) //Constructor. Custom values.
{
this->a = a;
this->b = b;
this->c = c;
this->d = d;
}
template <typename T = int,
typename = typename std::enable_if<std::is_same<T, int>::value ||
std::is_same<T, char>::value ||
std::is_same<T, long>::value ||
std::is_same<T, bool>::value,
void>::type>
T GetData()
{
if (std::is_same<T, char>::value)
{
return b;
}
if (std::is_same<T, long>::value)
{
return c;
}
if (std::is_same<T, bool>::value)
{
return d;
}
return a;
}
};
int main()
{
Store store { 63, '#', 65, true };
std::cout << store.GetData() << std::endl;
std::cout << store.GetData<>() << std::endl;
std::cout << store.GetData<int>() << std::endl;
std::cout << store.GetData<char>() << std::endl;
std::cout << store.GetData<long>() << std::endl;
std::cout << std::boolalpha << store.GetData<bool>() << std::endl;
}
Output
63
63
63
#
65
true
Compile
clang++ ./main.cpp -std=c++11 or g++ ./main.cpp -std=c++11
Check/run this code in https://repl.it/#JomaCorpFX/FunctionSpecialization#main.cpp
std::tuple basically does this, and your type is basically a tuple. So the easy and fast way is to just reuse std::tuple's machinery.
In c++14 it might look like this:
template<STORE_ENUM e>
auto get( Store s ){
return std::get<(unsigned)e>(std::make_tuple(s.a,s.b,s.c,s.d));
}
template<STORE_ENUM e, class T>
void set( Store& s, T t ){
std::get<(unsigned)e>(std::tie(s.a,s.b,s.c,s.d))=t;
}
This is c++14, but the missing bit for c++11 is easy:
template<STORE_ENUM e>
using store_type = typename std::tuple_element<(unsigned)e, std::tuple<int,char,long,bool>>::type;
template<STORE_ENUM e>
store_type<e> get( Store s ) {
return std::get<(unsigned)e>(std::make_tuple(s.a,s.b,s.c,s.d));
}
template<STORE_ENUM e>
void set( Store& s, store_type<e> v ){
std::get<(unsigned)e>(std::tie(s.a,s.b,s.c,s.d))=v;
}

Selecting a method using different enable_if conditions

I want to write a generic validate function. So i tried writing a meta program.
But it does not gets compiled, and rightly so. Can anyone tell me a way to achieve it.
I am posting my sample code. There can be 3 or more types of structs (here A, B, C), some having a particular type of header, another having other type of header and some even not having a header. So i want to write a program which correctly choose the required function (here f1(), f2() to validate a struct header. I don't want to use Boost Hana or any other reflection library.
#include <iostream>
using namespace std;
struct Header
{
int i;
};
struct OrderHeader
{
int i; int j;
};
struct A
{
Header header;
int val;
};
struct B
{
OrderHeader order_header;
int val;
int c;
};
struct C
{
int val;
int c;
};
bool f1(Header h)
{
return h.i == 1 ? true : false;
}
bool f2(OrderHeader oh)
{
return (oh.i == 1 and oh.j == 1) ? true : false;
}
template<typename St, typename = enable_if_t<is_same_v<decltype(St::header), Header>>>
using v1 = bool;
template<typename St, typename = enable_if_t<is_same_v<decltype(St::order_header), OrderHeader>>>
using v2 = bool;
template<typename St>
bool validate(St s)
{
if constexpr(is_same_v<v1<St>, bool>)
{
return f1(s.header);
}
else if constexpr(is_same_v<v2<St>, bool>)
{
return f2(s.order_header);
}
return true;
}
int main(int argc, char** argv)
{
A at{1,1};
A af{};
C c{};
B b{};
cout << boolalpha << validate(at) << endl;
cout << boolalpha << validate(af) << endl;
cout << boolalpha << validate(b) << endl;
cout << boolalpha << validate(c) << endl;
return 0;
}
if constexpr can be a means for partial compilation, but the condition inside if must always be compilable. In your case v1<St> and v2<St> only exist when St is of the right type, hence the errors.
You can use specialization of variable templates instead, e.g. like this
template<typename, typename = void>
constexpr bool is_v1 = false;
template<typename St>
constexpr bool is_v1<St, enable_if_t<is_same_v<decltype(St::header), Header>>> = true;
template<typename, typename = void>
constexpr bool is_v2 = false;
template<typename St>
constexpr bool is_v2<St, enable_if_t<is_same_v<decltype(St::order_header), OrderHeader>>> = true;
template<typename St>
bool validate(St s)
{
if constexpr (is_v1<St>)
{
return f1(s.header);
}
else if constexpr (is_v2<St>)
{
return f2(s.order_header);
}
return true;
}
Now is_v1<St> and is_v2<St> always return some value (either true or false), and the code should compile1.
1 There's also a typo in f2(): oh.i == 1 and oh.j == 1 should be oh.i == 1 && oh.j == 1.
Also note h.i == 1 ? true : false is tautologous, just h.i == 1 is enough.

C++ How does this code work (enable_if constructor/method)?

I know these two topics have been discussed before, but I still don't have a clear idea of how enable of a constructor and enable of a method works.
Here is a nice clear example that I created.
#include <type_traits>
#include <string>
#include <iostream>
template<bool B> using EnableConstructorIf = typename std::enable_if<B, int>::type;
template<bool B, class T> using EnableMethodIf = typename std::enable_if<B,T>::type;
template <int N>
class MyClass {
public:
std::string s;
template<int M=N, EnableConstructorIf< (M<0) > = 0> MyClass() {
s = "Negative";
}
template<int M=N, EnableConstructorIf< (M==0) > = 0> MyClass() {
s = "Zero";
}
template<int M=N, EnableConstructorIf< (M>0) > = 0 > MyClass() {
s = "Positive";
}
template<int M=N> EnableMethodIf< (M<0), int> getSign() {
return -1;
}
template<int M=N> EnableMethodIf< (M==0), int> getSign() {
return 0;
}
template<int M=N> EnableMethodIf< (M>0), int> getSign() {
return +1;
}
};
int main(int argc, char *argv[])
{
using namespace std;
MyClass<-5> a;
MyClass<0> b;
MyClass<100> c;
cout << "a.string = " << a.s <<" ->"<< a.getSign() << endl;
cout << "b.string = " << b.s <<" ->"<< b.getSign() << endl;
cout << "c.string = " << c.s <<" ->"<< c.getSign() << endl;
return 0;
}
It compiles and produces the following output, as expected. But how does it work?
a.string = Negative ->-1
b.string = Zero ->0
c.string = Positive ->1

Elegant template specialization

Is there an elegant way to specialize a template based on one of its template parameters?
Ie.
template<int N> struct Junk {
static int foo() {
// stuff
return Junk<N - 1>::foo();
}
};
// compile error: template argument '(size * 5)' involves template parameter(s)
template<int N> struct Junk<N*5> {
static int foo() {
// stuff
return N;
}
};
template<> struct Junk<0> {
static int foo() {
// stuff
return 0;
}
};
Ie. I am trying to specialize a template based on the parameter being divisible by 5. The only way I can seem to do it is like below:
template<int N> struct JunkDivisibleBy5 {
static int foo() {
// stuff
return N;
}
};
template<int N> struct Junk {
static int foo() {
// stuff
if ((N - 1) % 5 == 0 && N != 1)
return JunkDivisibleBy5<N - 1>::foo();
else
return Junk<N - 1>::foo();
}
};
template<> struct Junk<0> {
static int foo() {
// stuff
return 0;
}
};
But this is significantly less elegant, and also necessitates instantiation of all templates even if the template argument shouldn't require it.
How's this:
#include <iostream>
using namespace std;
template < typename T, T N, T D >
struct fraction {
typedef T value_type;
static const value_type num = N;
static const value_type denom = D;
static const bool is_div = (num % denom == 0);
};
template< typename T, T N, T D, bool P >
struct do_if {
static void op() { cout << N << " NOT divisible by " << D << endl; }
};
template< typename T, T N, T D >
struct do_if< T, N, D, true > {
static void op() { cout << N << " divisible by " << D << endl; }
};
template < int N >
void foo() {
typedef fraction< int, N, 5 > f;
do_if< typename f::value_type, f::num, f::denom, f::is_div >::op();
}
int main() {
foo< -5 >();
foo< -1 >();
foo< 0 >();
foo< 1 >();
foo< 5 >();
foo< 10000005 >();
return 0;
}
Using D programming language templates, one could write it as:
struct Junk(int N)
{
static int foo()
{
static if (N == 0)
return 0;
else static if ((N % 5) == 0)
return N;
else
return Junk!(N - 1).foo();
}
}
static if's are executed at compile time.
All calculations could be made in compile-time:
#include <iostream>
template<int N> struct Junk {
enum { IsDivisibleBy5 = (N % 5 == 0) };
template<bool D> struct JunkInternal {
enum { Result = Junk<N-1>::Result };
};
template<> struct JunkInternal<true> {
enum { Result = N };
};
enum { Result = JunkInternal<IsDivisibleBy5>::Result };
};
int main(int, char**)
{
std::cout << Junk< 0 >::Result << std::endl;
std::cout << Junk< 7 >::Result << std::endl;
std::cout << Junk< 10 >::Result << std::endl;
return 0;
}
Code
template<int A, bool = !(A % 5)>
struct select : select<A-1> { };
template<int A>
struct select<A, true> { static int const value = A; };
template<>
struct select<0, true> { static int const value = 0; };
int main() {
std::cout << select<1>::value; // 0
std::cout << select<7>::value; // 5
std::cout << select<10>::value; // 10
}
Keep the divisor variable
template<int A, int D, bool = !(A % D)>
struct select : select<A-1, D> { };
template<int A, int D>
struct select<A, D, true> { static int const value = A; };
template<int D>
struct select<0, D, true> { static int const value = 0; };
int main() {
std::cout << select<1, 3>::value; // 0
std::cout << select<7, 3>::value; // 6
std::cout << select<10, 3>::value; // 9
}
Inheritance works quite well:
template<int N> struct Junk : private JunkBase < N % 5 > { };
template<int N> struct JunkBase {
static int foo() {
// stuff
return Junk<N - 1>::foo();
}
};
template< > struct JunkBase<0> {
static int foo() {
return 0;
}
};
You might need to pass N to JunkBase::foo, if you need N/5 too.
I would hardly call it elegant, but here's my version of your code using only templates for computation (along with a test thing) --
#include <iostream>
template < int N > struct JunkDivBy5 {
static int foo() {
return N;
}
};
template < int N > struct Junk {
template < int N1 > struct _JunkCond {
enum { val = ( N1 != 1 && ( N1 - 1 ) % 5 == 0 ) ? 1 : 0 };
};
template < int M, int N1 > struct _JunkBranch { /* Error */ };
template < int N1 > struct _JunkBranch< 1, N1 > {
typedef JunkDivBy5< N1 - 1 > Type;
};
template < int N1 > struct _JunkBranch< 0, N1 > {
typedef Junk< N1 - 1 > Type;
};
static int foo() {
return _JunkBranch< _JunkCond< N >::val, N >::Type::foo();
}
};
template <> struct Junk< 0 > {
static int foo() {
return 0;
}
};
int main( int argc, char *argv[] ) {
std::cout << Junk< 0 >::foo() << std::endl;
std::cout << Junk< 5 >::foo() << std::endl;
std::cout << Junk< 7 >::foo() << std::endl;
std::cout << Junk< 25 >::foo() << std::endl;
}