Мой код должен проверять различные типы пикселей на «достоверность». Например, пиксели с плавающей запятой недопустимы, если они сообщают true
для std::isnan()
.
Итак, у меня есть структура шаблона «валидатор», которую я специализирую для своих различных типов пикселей (здесь, только для float
). Мой код использует глобальную шаблонную функцию для вызова правильной перегрузки через SFINAE
// Dummy implementation breaks compilation if no overload found.
template<class PEL, typename Enable=void> struct pixel_validator { };
template<class PEL>
struct pixel_validator<PEL, typename std::enable_if<std::is_floating_point<PEL>::value>::type>
{
static bool validate(const PEL& p) { return !std::isnan(p); }
};
template<class PEL>
inline bool is_valid_pixel(const PEL& p)
{
// Dispatch to validator above
return pixel_validator<PEL>::validate(p);
};
void main
{
float x = 1.0f;
std::cout << "is it valid ?" << std::boolalpha << is_valid_pixel(x);
}
И этот пример работает просто отлично. Специализация pixel_validator
для float
выбрана. Все хорошо.
Но затем я попытался уменьшить детализацию шаблонных выражений для ясности с помощью пользовательской версии "std::enable_if
" специально для float
.
template<class T, class VAL=T>
struct enable_if_floating
: std::enable_if<std::is_floating_point<T>::value, VAL>
{};
Так что теперь вместо того, чтобы писать это:
std::enable_if<std::is_floating_point<PEL>::value>::type
Я могу написать
enable_if_floating<PEL>::value
... поэтому мой валидатор становится:
template<class PEL>
struct pixel_validator<PEL, typename enable_if_floating<PEL>::type>
{
static bool validate(const PEL& p) { return !std::isnan(p); }
};
К сожалению, в тот момент, когда я изменил свой "pixel_validator
" на использование, код не может быть собран. Мой enable_if_floating
не работает, и поэтому Visual Studio не может найти соответствующую специализацию. Мой вывод не удивителен.
1>------ Build started: Project: TestApp7, Configuration: Debug Win32 ------
1>TestApp7.cpp
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: 'validate': is not a member of 'pixel_validator<PEL,void>'
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: with
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: [
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: PEL=float
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: ]
1>C:\Test\TestApp7\TestApp7.cpp(62): message : see declaration of 'pixel_validator<PEL,void>'
1>C:\Test\TestApp7\TestApp7.cpp(62): message : with
1>C:\Test\TestApp7\TestApp7.cpp(62): message : [
1>C:\Test\TestApp7\TestApp7.cpp(62): message : PEL=float
1>C:\Test\TestApp7\TestApp7.cpp(62): message : ]
1>C:\Test\TestApp7\TestApp7.cpp(82): message : see reference to function template instantiation 'bool is_valid_pixel<float>(const PEL &)' being compiled
1>C:\Test\TestApp7\TestApp7.cpp(82): message : with
1>C:\Test\TestApp7\TestApp7.cpp(82): message : [
1>C:\Test\TestApp7\TestApp7.cpp(82): message : PEL=float
1>C:\Test\TestApp7\TestApp7.cpp(82): message : ]
1>C:\Test\TestApp7\TestApp7.cpp(62,1): error C3861: 'validate': identifier not found
1>Done building project "TestApp7.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Мой вопрос: почему? Что не так с моим enable_if_floating
?
Примечание: я даже поместил этот код в main()
, просто для проверки работоспособности. Если бы мой шаблон был плохим, я бы ожидал, что static_assert()
потерпит неудачу, но это не так.
// Sanity check #2. Does my enable_if_floating test reports that float
// enables because it's numeric? If not then the static_assert below should fail
using float_type = enable_if_floating<float>::type;
static_assert(std::is_same_v<float_type, float>, "Not same as float...");
Примечание также: мой код реального мира использует предикат, который экономит намного больше места, чем в этом простом примере