在 SFINAE 中无法将概念类型识别为 bool
failed to recognize concept type as bool in SFINAE
考虑这个例子:
#include <iostream>
#include <utility>
template<typename T>
concept Printable = requires(const T a) {
a.print();
};
template<typename T>
constexpr auto is_printable() {
return Printable<T>;
}
template<class T, std::enable_if_t<is_printable<T>()>* = nullptr>
constexpr void do_print(T data) {
data.print();
}
struct foo {
void print() const {
std::cout << "Hello World\n";
}
};
int main() {
foo f;
do_print(f);
}
尝试在 MSVC(版本 16.9.4,/std:c++latest)上编译它会产生这些错误:
Error C2783 'void do_print(T)': could not deduce template argument for '__formal'
Error C2672 'do_print': no matching overloaded function found
未能满足std::enable_if_t
。
我发现错误来自 constexpr auto is_printable() { ... }
中的 auto
,将 auto
替换为 bool
将正确编译。
template<typename T>
constexpr bool is_printable() {
return Printable<T>;
}
我觉得这很奇怪,概念 Printable<T>
在编译时计算,应该产生 constexpr bool
。为什么 auto
突然失败?
这是一个 MSVC 错误。你的代码是正确的。我强烈建议报告该问题。 Your code works correctly on GCC and Clang.
在此期间,我会简单地放弃 SFINAE。当您获得替换 enable ifs 的概念时,实际上并不需要它:
#include <iostream>
#include <utility>
template<typename T>
concept Printable = requires(const T a) {
a.print();
};
constexpr void do_print(Printable auto data) {
data.print();
}
struct foo {
void print() const {
std::cout << "Hello World\n";
}
};
int main() {
foo f;
do_print(f);
}
您也可以使用 requires
甚至用您的概念替换 typename
:
template<typename T> requires Printable<T>
constexpr void do_print(T data) {
data.print();
}
template<Printable T>
constexpr void do_print(T data) {
data.print();
}
考虑这个例子:
#include <iostream>
#include <utility>
template<typename T>
concept Printable = requires(const T a) {
a.print();
};
template<typename T>
constexpr auto is_printable() {
return Printable<T>;
}
template<class T, std::enable_if_t<is_printable<T>()>* = nullptr>
constexpr void do_print(T data) {
data.print();
}
struct foo {
void print() const {
std::cout << "Hello World\n";
}
};
int main() {
foo f;
do_print(f);
}
尝试在 MSVC(版本 16.9.4,/std:c++latest)上编译它会产生这些错误:
Error C2783 'void do_print(T)': could not deduce template argument for '__formal'
Error C2672 'do_print': no matching overloaded function found
未能满足std::enable_if_t
。
我发现错误来自 constexpr auto is_printable() { ... }
中的 auto
,将 auto
替换为 bool
将正确编译。
template<typename T>
constexpr bool is_printable() {
return Printable<T>;
}
我觉得这很奇怪,概念 Printable<T>
在编译时计算,应该产生 constexpr bool
。为什么 auto
突然失败?
这是一个 MSVC 错误。你的代码是正确的。我强烈建议报告该问题。 Your code works correctly on GCC and Clang.
在此期间,我会简单地放弃 SFINAE。当您获得替换 enable ifs 的概念时,实际上并不需要它:
#include <iostream>
#include <utility>
template<typename T>
concept Printable = requires(const T a) {
a.print();
};
constexpr void do_print(Printable auto data) {
data.print();
}
struct foo {
void print() const {
std::cout << "Hello World\n";
}
};
int main() {
foo f;
do_print(f);
}
您也可以使用 requires
甚至用您的概念替换 typename
:
template<typename T> requires Printable<T>
constexpr void do_print(T data) {
data.print();
}
template<Printable T>
constexpr void do_print(T data) {
data.print();
}