static_assert usage: What am I missing here?

102 Views Asked by At

I would like to reference two earlier posts:

why-is-comparing-two-parameters-of-a-constexpr-function-not-a-constant-condition

how-does-this-function-template-deduce-the-size-of-an-array

In the first discussion, it has been pointed out that the compilation error

error: non-constant condition for static assertion

is due to the fact that the constexpr function under consideration could be invoked with arguments evaluated during run-time.

In the second discussion, it has been pointed out that the template function method for getting at the size of the template array, works due to template argument type deduction by the compiler, which happens during compilation.

The following code gives me this error for static assertion:

In file included from main.cpp:1:
classA.h: In instantiation of ‘void doSomething(A<T> (&)[2]) [with T = int; array2As<T> = A<int> [2]]’:
main.cpp:6:18:   required from here
classA.h:65:20: error: non-constant condition for static assertion
   65 |    static_assert(2 == sz, "Compilation error: array must have exactly 2 elements");
      |                  ~~^~~~~
compilation terminated due to -Wfatal-errors

//classA.h

#include <type_traits>
#include <cstddef>
//#include <iterator>
#include <iostream>

using std::is_same;
//using std::size;
using std::size_t;
using std::cout;
using std::endl;

template<typename T> class A;
template<typename T>
using array2As = A<T>[2];

template<typename T> 
void doSomething (array2As<T>&);

template<template<typename>class A, typename T, size_t N>
constexpr size_t cal_size(const A<T>(&)[N]){
 return N;
}

template<typename T>
class A{
  public:
  A(T);
  private:
  friend void doSomething<>(array2As<T>&);
  A()=delete;
  A(const A&)=delete; 
  A& operator=(const A&)=delete;
  T elem;
};

template<typename T>
A<T>::A(T elem){
  static_assert(is_same<T,int>::value || is_same<T,double>::value, "Compilation error: type must be int or double");
  this->elem = elem;
}

template<typename T> void doSomething (array2As<T>& a){
auto sz = cal_size(a);
   cout << sz << endl;
   static_assert(2 == sz, "Compilation error: array must have exactly 2 elements");
  
  const auto& obj1 = a[0];
  cout << obj1.elem << endl;
  const auto& obj2 = a[1];
  cout << obj2.elem << endl;
 return;
}

//main.cpp

#include "classA.h"

int main (){
 
 array2As<int> a = {A(5),A(7)};
 doSomething<int>(a);
 array2As<double> b = {A(1.2),A(6.3)};
 doSomething<double>(b);

 return 0;
}

The methods involved, i.e., cal_size() and doSomething() are function templates themselves, so going by the explanation in the second post, the value stored inside the variable sz as returned from cal_size() should be a compile time constant.

So why is it that I am still getting this error?

TIA

0

There are 0 best solutions below