我试图做一个简单的LookupTable中基于整数数组,这里的想法是有它在编译时计算上。简单constexpr LookupTable中C++ 14
试图使它可以用于我可能有的各种整数类型的任何其他未来表格,我可能需要它,我需要它作为模板。
所以我有一个LookUpTable.h
#ifndef LOOKUPTABLE_H
#define LOOKUPTABLE_H
#include <stdexcept> // out_of_range
template <typename T, std::size_t NUMBER_OF_ELEMENTS>
class LookUpTableIndexed
{
private:
//constexpr static std::size_t NUMBER_OF_ELEMENTS = N;
// LookUpTable
T m_lut[ NUMBER_OF_ELEMENTS ] {}; // ESSENTIAL T Default Constructor for COMPILE-TIME INTERPRETER!
public:
// Construct and Populate the LookUpTable such that;
// INDICES of values are MAPPED to the DATA values stored
constexpr LookUpTableIndexed() : m_lut {}
{
//ctor
}
// Returns the number of values stored
constexpr std::size_t size() const {return NUMBER_OF_ELEMENTS;}
// Returns the DATA value at the given INDEX
constexpr T& operator[](std::size_t n)
{
if (n < NUMBER_OF_ELEMENTS)
return m_lut[n];
else throw std::out_of_range("LookUpTableIndexed[] : OutOfRange!");
}
constexpr const T& operator[](std::size_t n) const
{
if (n < NUMBER_OF_ELEMENTS)
return m_lut[n];
else throw std::out_of_range("LookUpTableIndexed[] const : OutOfRange!");
}
using iterator = T*;
// Returns beginning and end of LookUpTable
constexpr iterator begin() {return &m_lut[0 ];}
constexpr iterator end () {return &m_lut[NUMBER_OF_ELEMENTS];}
};
#endif // LOOKUPTABLE_H
而且我试图使用它在一个类的整数信号WRT的整数距离的快速衰减。
例如。这仅仅是一个样品用法foo.h中
#ifndef FOO_H
#define FOO_H
#include <limits> // max, digits
#include <stdlib.h> // abs
#include "LookUpTable.h" // LookUpTableIndexed
class Foo
{
private:
template <typename TDistance,
TDistance MAXIMUM_DISTANCE,
std::size_t NUMBER_OF_DIGITS>
struct DistanceAttenuation
{
private:
// Maximum value that can be held in this type
//constexpr auto MAXIMUM_DISTANCE = std::numeric_limits<TDistance>::max();
// Number of bits used by this type
//constexpr auto NUMBER_OF_DIGITS = std::numeric_limits<TDistance>::digits;
// LookUpTable
LookUpTableIndexed<TDistance, NUMBER_OF_DIGITS> m_attenuationRangeUpperLimit {}; // ESSENTIAL LookUpTable Default Constructor for COMPILE-TIME INTERPRETER!
// Returns the number of bits to BIT-SHIFT-RIGHT, attenuate, some signal
// given its distance from source
constexpr std::size_t attenuateBy(const TDistance distance)
{
for (std::size_t i {NUMBER_OF_DIGITS}; (i > 0); --i)
{
// While distance exceeds upper-limit, keep trying values
if (distance >= m_attenuationRangeUpperLimit[i - 1])
{
// Found RANGE the given distance occupies
return (i - 1);
}
}
throw std::logic_error("DistanceAttenuation::attenuateBy(Cannot attenuate signal using given distance!)");
}
public:
// Calculate the distance correction factors for signals
// so they can be attenuated to emulate the the effects of distance on signal strength
// ...USING THE INVERSE SQUARE RELATIONSHIP OF DISTANCE TO SIGNAL STRENGTH
constexpr DistanceAttenuation() : m_attenuationRangeUpperLimit {}
{
//ctor
// Populate the LookUpTable
for (std::size_t i {0}; (i < NUMBER_OF_DIGITS); ++i)
{
TDistance goo = 0; // Not an attenuation calculation
TDistance hoo = 0; // **FOR TEST ONLY!**
m_attenuationRangeUpperLimit[i] = MAXIMUM_DISTANCE - goo - hoo;
}
static_assert((m_attenuationRangeUpperLimit[0] == MAXIMUM_DISTANCE),
"DistanceAttenuation : Failed to Build LUT!");
}
// Attenuate the signal, s, by the effect of the distance
// by some factor, a, where;
// Positive contribution values are attenuated DOWN toward ZERO
// Negative UP ZERO
constexpr signed int attenuateSignal(const signed int s, const int a)
{
return (s < 0)? -(abs(s) >> a) :
(abs(s) >> a);
}
constexpr signed int attenuateSignalByDistance(const signed int s, const TDistance d)
{
return attenuateSignal(s, attenuateBy(d));
}
};
using SDistance_t = unsigned int;
constexpr static auto m_distanceAttenuation = DistanceAttenuation<SDistance_t,
std::numeric_limits<SDistance_t>::max(),
std::numeric_limits<SDistance_t>::digits>();
public:
Foo() {}
~Foo() {}
// Do some integer foo
signed int attenuateFoo(signed int signal, SDistance_t distance) {return m_distanceAttenuation::attenuateSignalByDistance(signal, distance);}
};
#endif // FOO_H
我试图通过CppCon 2015年这样做有几个方法,使用YouTube视频教程:斯科特·舒尔“constexpr:应用”等人,但它不会给编译错误;
error: 'constexpr static auto m_distanceAttenuation...' used before its definition
和静态断言失败,
error: non-constant condition for static assertion
表示它不计算任何东西编译时间。
我是C++新手。
我知道我在做一些明显的事情,但我不知道它是什么。
我是否滥用static or constexpr?
numeric_limits是否是constexpr?
我在做什么错? 谢谢。
对于一个你缺少收盘'>''为= DistanceAttenuation <...'。这是一个复制错误?除此之外,我非常怀疑,你可以在'DistanceAttenuation'的构造函数中做你想做的事情,但是我还没有使用C++ 14的constexpr。 – MikeMB
您是否尝试了解非常明确的编译器错误消息建议您应该执行的操作?你知道“定义之前使用”是什么意思吗? –
不知道正确的答案,但:1)“在定义之前使用”似乎是由使用嵌套类引起的。如果您将DistanceAttenuation移出Foo,它将起作用。 2)如果需要,constexpr构造函数必须是可编译的,以便在运行时运行,在这种情况下,'static_assert'内的表达式不会被constexpr。 – michalsrb