In my image class I provide direct memory access to a specific row using the following const overloaded templated functions
template <typename T>
inline T* Image::getRow(unsigned int y)
{
...
}
template <typename T>
inline const T* Image::getRow(unsigned int y) const
{
...
}
However, if I specify another templated function that actually uses these as:
template <typename T>
void Image::compute(...)
{
...
T* pImageRow = getRow<T>(y); //error C2668
...
}
I get the following error error C2668: 'Image::getRow': ambiguous call to overloaded function
.
Is there any way to tell the compiler that it should actually use the non-const variant of Image::getRow
?`
Minimal Example
Working on an reproducible example, I found out that the problem is appearantly somewhat deeper (actually if I call getRow
from a lambda function parallelFor
):
Minimal example is here:
inline void parallelFor(unsigned int endIndex, const std::function<void(unsigned int i)>& computeFunction, unsigned int startIdx = 0)
{
#pragma omp parallel for
for(int i = startIdx; i < (int)endIndex; i++)
{
computeFunction((unsigned int)i);
}
}
class Image
{
public:
template <typename T>
T* getRow(unsigned int y);
template <typename T>
const T* getRow(unsigned int y) const;
template <typename T>
void compute(const std::function<void(unsigned int x, unsigned int y, T& data)>& computeFunction);
};
template <typename T>
inline T* Image::getRow(unsigned int y)
{
return (T*)nullptr;
}
template <typename T>
inline const T* Image::getRow(unsigned int y) const
{
return (const T*)nullptr;
}
template <typename T>
void Image::compute(const std::function<void(unsigned int x, unsigned int y, T& data)>& computeFunction)
{
unsigned int rows = 10;
unsigned int cols = 10;
parallelFor(rows,
[&](unsigned int y)
{
T* pImageRow = getRow<T>(y);
for(unsigned int x = 0; x < cols; x++)
{
T& curVal = pImageRow[x];
computeFunction(x, y, curVal);
}
});
}
int main(int argc, char** argv)
{
Image a;
a.compute<unsigned char>([](unsigned int x, unsigned int y, unsigned char& color) { color = 0; });
return 0;
}