0

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

5
  • 1
    cal_size(a) is (currently) a constant expression, but you store its result into a non-const(expr) variable which can have its value changed at any point at runtime, so sz isn't usable in constant expressions. Add constexpr on its declaration. And then it will likely still fail because there is a recent defect report against the standard that your compiler likely hasn't implemented yet before which cal_size(a) was not a constant expression specifically because a is a reference. Commented Sep 9, 2023 at 21:20
  • @user17732522 I tried changing sz to constexpr and ran into the error that you are referring to Commented Sep 9, 2023 at 21:22
  • @user17732522 this is in spite of changing the parameter type of doSomething to const...any thoughts? Commented Sep 9, 2023 at 21:24
  • As long as your compiler doesn't implement the DR, it is impossible to calculate the size by passing a by-reference which is necessary for a built-in array to even have the type information. Passing a std::array by-value would work. If you still want to do it your way, you need to operate directly on the type of a, not a itself. E.g. by using std::extent instead of your cal_size. Commented Sep 9, 2023 at 21:25
  • In fact a generalization of your issue was the first question I posted myself here: stackoverflow.com/questions/70482497/… Commented Sep 9, 2023 at 21:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.