C ++ template output of array size for specified template in header file

I am reading Meyers book in modern C ++, where I can find a piece of code:

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&) [N]) noexcept {
  return N;
}

This function prints Nfor us as a compile-time constant. So I want to apply it in my code:

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&) [N]) noexcept {
  return N;
}

template <typename T>
class A {
  public:
    const static char* names[];
};

template<typename T>
const char* A<T>::names[] = {"foo", "bar"};

template<>
const char* A<bool>::names[] = {"foo","bar", "foobar"};

If put in one file, it works fine, arraySize(A<int>::names)is 2and arraySize(A<bool>::names)is 3.

But when used in a larger project requiring separate .hand .cpp, the problem arises:

  • If you put the declaration of the specified version A<bool>::names[]in .cpp, the code compiles (and the links), but the compiler cannot see it at the output arraySize(), therefore it arraySize(A<bool>::names)is displayed on 2.

  • A<bool>::names[] .h, , " ".

, arraySize(A<bool>::names) 3?

+4
2

constexpr, ++ 11 ( ).

, class A names ( names), static constexpr ( ), class ( ) ( cpp, ) .

, , ++ 17, .

#include <iostream>

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&) [N]) noexcept {
  return N;
}

template <typename T>
class A {
   public:
     static constexpr char const * names[] = {"foo", "bar"};
};

template <>
class A<bool> {
   public:
     static constexpr char const * names[] = {"foo", "bar", "foobar"};

};

template<typename T>
constexpr char const * A<T>::names[];

constexpr char const * A<bool>::names[];


int main()
 {
   std::cout << arraySize(A<long>::names) << std::endl; // print 2
   std::cout << arraySize(A<bool>::names) << std::endl; // print 3
 }

--- EDIT ---

OP

. , " " , .

, names base (namesB, base-for-names), names.

namesB class A.

#include <iostream>

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&) [N]) noexcept
 { return N; }

template <typename T>
struct namesB
 { static constexpr char const * names[] = {"foo", "bar"}; };

template <>
struct namesB<bool>
 { static constexpr char const * names[] = {"foo", "bar", "foobar"}; };

template <typename T>
class A : public namesB<T>
 { /* a complex class defined only one time */ };


template<typename T>
constexpr char const * namesB<T>::names[];

constexpr char const * namesB<bool>::names[];


int main()
 {
   std::cout << arraySize(A<long>::names) << std::endl; // print 2
   std::cout << arraySize(A<bool>::names) << std::endl; // print 3
 }
+1

.cpp , , . , , .

, , , , int , , . , .cpp. , .cpp - , .tpp . , .h, , .

0

Source: https://habr.com/ru/post/1666117/


All Articles