Using variable template inside constexpr built-in function without displaying variable template?

Is it possible to use a variable template inside the constexpr built-in function without displaying the variable template itself?

For example, this compiles and works:

template<typename T> constexpr T twelve_hundred = T(1200.0);

template<typename T>
inline constexpr T centsToOctaves(const T cents) {
    return cents / twelve_hundred<T>;
}

But this does not compile:

template<typename T>
inline constexpr T centsToOctaves(const T cents) {
    template<typename U> constexpr U twelve_hundred = U(1200.0);
    return cents / twelve_hundred<T>;
}

The reason is that template declarations are not allowed in the block area (GCC gives an informative error message, Clang does not).

To repeat the motivation in more detail, this function is built-in and defined in the header, and I'm not interested in placing the variable template wherever the header is included.

I suppose that I can define the namespace of the parts and place the variable template there, but it would be better not to expose the variable template at all. Perhaps this is not possible.

+4
2

, :

- . [...]. , , . [...]

.

, .
, -, :

class C {
    template<typename T>
    static constexpr T twelve_hundred = T(1200.0);

public:
    template<typename T>
    static constexpr T centsToOctaves(const T cents) {
        return cents / twelve_hundred<T>;
    }
};

int main() {
    C::centsToOctaves(42);
}

:

class C {
    template<typename T>
    static constexpr T twelve_hundred = T(1200.0);

    template<typename T>
    friend inline constexpr T centsToOctaves(const T cents);
};

template<typename T>
inline constexpr T centsToOctaves(const T cents) {
    return cents / C::twelve_hundred<T>;
}

int main() {
    centsToOctaves(42);
}

, centsToOctaves - C, .

, , :

template<typename T>
inline constexpr T centsToOctaves(const T cents) {
    return cents / T{1200};
}
+3

, . .

class Detail {
 public:
  template<typename T>
  static constexpr T centsToOctaves(const T cents) {
    return cents / twelve_hundred<T>;
  }

 private:
  template<typename U>
  static constexpr U twelve_hundred = U(1200.0);
};

// forwarding
template<typename T>
inline constexpr T centsToOctaves(const T cents) {
  return Detail::centsToOctaves<T>(cents);
}

int main() {
  centsToOctaves<int>(12);
  return 0;
}

Unrelated:

template constexpr. , :

template<typename T>
inline constexpr T centsToOctaves(const T cents) {
    using U = T;
    return cents / U(1200.0);
}

, .

template <>
inline constexpr int centsToOctaves(const int cents) {
    using U = int;
    return cents / U(1200.0);
}

, , , .

0

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


All Articles