您可以使用 std::is_detected 检测 class 的模板成员吗
Can you detect template member of a class using std::is_detected
我用std::experimental::is_detected
判断class是否有某些成员函数:
#include <utility>
#include <experimental/type_traits>
template<typename USC>
class Descriptor
{
private:
template<class T>
using has_member1_t =
decltype(std::declval<T>().member1(std::declval<std::vector<char> &>()));
public:
static constexpr bool has_member1 =
std::experimental::is_detected_convertible_v<long long,
has_member1_t,
USC>;
};
问题是我还需要确定 class 是否具有某些具有以下签名的 模板成员函数 :
template<typename Derived>
int member2(Eigen::ArrayBase<Derived> &&)
我试过这样做:
//Inside Descriptor
template<class T, class U>
using has_member2_t =
decltype(std::declval<T>().member2(std::declval<Eigen::ArrayBase<U> &&>()));
static constexpr bool has_member2 =
std::experimental::is_detected_convertible_v<long long,
has_member2_t,
USC>;
但它不起作用。由于我对 C++ TMP 没有真正的经验,我想知道有没有办法用 std::experimental::is_detected
或其他一些实用程序来实现这一点?
如果 c++20 是一个选项,这种代码已经通过使用概念变得更容易阅读和编写。
#include <iostream>
#include <vector>
struct Foo {
int member1(int) {
return 1;
}
template <typename T>
double member2(std::vector<T>) {
return 2.5;
}
};
struct Bar {};
template <typename T>
concept MyConcept = requires (T t) {
{ t.member1(0) } -> std::same_as<int>; // We can check return type
{ t.template member2<int>(std::vector<int>{}) }; // but we don't have to
};
int main() {
static_assert(MyConcept<Foo>);
static_assert(!MyConcept<Bar>);
}
您尝试的问题是您没有将任何内容作为 U
传递给检查。我还将修改它以使用 .template member2<...>
语法来显式检查模板。
这是一个例子。
#include <iostream>
#include <vector>
#include <utility>
#include <experimental/type_traits>
struct Foo {
int member1(int) {
return 1;
}
template <typename T>
double member2(std::vector<T>) {
return 2.5;
}
};
struct Bar {};
template<class T, class U>
using has_member2_t =
decltype(std::declval<T>().template member2<U>(std::declval<std::vector<U> &&>()));
int main() {
static constexpr bool has_member2_Foo =
std::experimental::is_detected_convertible_v<long long,
has_member2_t,
Foo, double>;
static constexpr bool has_member2_Bar =
std::experimental::is_detected_convertible_v<long long,
has_member2_t,
Bar, double>;
static_assert(has_member2_Foo);
static_assert(!has_member2_Bar);
}
我用std::experimental::is_detected
判断class是否有某些成员函数:
#include <utility>
#include <experimental/type_traits>
template<typename USC>
class Descriptor
{
private:
template<class T>
using has_member1_t =
decltype(std::declval<T>().member1(std::declval<std::vector<char> &>()));
public:
static constexpr bool has_member1 =
std::experimental::is_detected_convertible_v<long long,
has_member1_t,
USC>;
};
问题是我还需要确定 class 是否具有某些具有以下签名的 模板成员函数 :
template<typename Derived>
int member2(Eigen::ArrayBase<Derived> &&)
我试过这样做:
//Inside Descriptor
template<class T, class U>
using has_member2_t =
decltype(std::declval<T>().member2(std::declval<Eigen::ArrayBase<U> &&>()));
static constexpr bool has_member2 =
std::experimental::is_detected_convertible_v<long long,
has_member2_t,
USC>;
但它不起作用。由于我对 C++ TMP 没有真正的经验,我想知道有没有办法用 std::experimental::is_detected
或其他一些实用程序来实现这一点?
如果 c++20 是一个选项,这种代码已经通过使用概念变得更容易阅读和编写。
#include <iostream>
#include <vector>
struct Foo {
int member1(int) {
return 1;
}
template <typename T>
double member2(std::vector<T>) {
return 2.5;
}
};
struct Bar {};
template <typename T>
concept MyConcept = requires (T t) {
{ t.member1(0) } -> std::same_as<int>; // We can check return type
{ t.template member2<int>(std::vector<int>{}) }; // but we don't have to
};
int main() {
static_assert(MyConcept<Foo>);
static_assert(!MyConcept<Bar>);
}
您尝试的问题是您没有将任何内容作为 U
传递给检查。我还将修改它以使用 .template member2<...>
语法来显式检查模板。
这是一个例子。
#include <iostream>
#include <vector>
#include <utility>
#include <experimental/type_traits>
struct Foo {
int member1(int) {
return 1;
}
template <typename T>
double member2(std::vector<T>) {
return 2.5;
}
};
struct Bar {};
template<class T, class U>
using has_member2_t =
decltype(std::declval<T>().template member2<U>(std::declval<std::vector<U> &&>()));
int main() {
static constexpr bool has_member2_Foo =
std::experimental::is_detected_convertible_v<long long,
has_member2_t,
Foo, double>;
static constexpr bool has_member2_Bar =
std::experimental::is_detected_convertible_v<long long,
has_member2_t,
Bar, double>;
static_assert(has_member2_Foo);
static_assert(!has_member2_Bar);
}