我想检查是否存在接受T参数类型的非成员函数.为此,我使用void_t了Walter E. Brown先生在cppcon上提出的"技巧"(同样的技巧没有任何问题,检查是否存在成员类型或成员函数).
#include <iostream>
#include <type_traits>
template<typename...>
using void_t = void;
void Serialize(float&)
{
}
template<typename T, typename = void>
struct has_external_serialize : std::false_type
{
};
template<typename T>
struct has_external_serialize<T, void_t<decltype(Serialize(std::declval<T&>()))>> : std::true_type
{
};
void Serialize(int&)
{
}
int main(int argc, const char * argv[])
{
std::cout<<has_external_serialize<float>::value<<has_external_serialize<int>::value;
}
Run Code Online (Sandbox Code Playgroud)
11使用GCC 10编译时以及使用clang(xcode 5.1.1)编译时,将打印此代码.
我的问题是 - 这段代码是否正确?如果是,是否存在clang中的错误或GCC中的错误,或者代码是在某个"实现定义"区域中,我不能假设它在所有平台上都有相同的行为?
我想写这样的东西:
template <class T>
using MyTypeOrTupple = typename std::conditional<has_member_type_MyType<T>::value,
typename T::MyType,
std::tuple<> >::type;
Run Code Online (Sandbox Code Playgroud)
我has_member_type_MyType使用https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector实现
然而,海湾合作委员会(4.8.4)仍然抱怨使用T::MyType何时MyType未定义T.有办法解决这个问题吗?
有没有办法在标题中的那个点上使用static_assert类型T 不完整?如果有人在他们不应该的地方添加#includes,那么这个想法就会产生编译错误.
使用该链接的答案,
namespace
{
template<class T, int discriminator>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
}
#define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value
class GType;
static_assert(!IS_COMPLETE(GType),"no cheating!");
Run Code Online (Sandbox Code Playgroud)
不幸的是,这给出了"无效使用incomlete类型"错误,哦.有没有办法断言否定?
我正在尝试Walter Brown的TMP演讲中的例子,我正在尝试让他的has_member实现工作.
然而,实现似乎错误地返回true,这使我相信有一些我不理解的SFINAE的细节.
#include <iostream>
#include <type_traits>
template <class ...>
using void_t = void;
template <class, class = void>
struct has_type_member: std::false_type {};
template <class T>
struct has_type_member<T, void_t<typename T::type> >: std::true_type {};
struct FooWithType
{
typedef int type;
};
struct FooNoType
{
};
int main()
{
std::cout << "Does FooWithType have type member? " <<
(has_type_member<FooWithType>() ? "YES" : "NO") << "\n";
std::cout << "Does FooNoType have type member? " <<
(has_type_member<FooNoType>() ? "YES" : …Run Code Online (Sandbox Code Playgroud) 我想实现一个小的trait类来确定一个类型是否已operator()正确重载,以便我可以查询类似的类型:
FunctorCheck<F, void(int, char)>::value
Run Code Online (Sandbox Code Playgroud)
最初,我对如何从这个问题实现这个问题有了一个想法,但在看了一篇关于TMP的Cppcon讲座之后,我突然意识到这个问题可以更优雅地解决.这就是我想出来的,它在Clang 3.5.0上编译并运行完美:
template <typename ...>
using void_t = void;
template <typename Functor, typename ... Args>
using FunctorReturn = decltype(declval<Functor>()(declval<Args>()...));
template <typename Functor, typename Signature, typename = void>
struct FunctorCheck: public std::false_type
{};
template <typename Functor, typename R, typename ... Args>
struct FunctorCheck<Functor, R(Args...),
void_t<FunctorReturn<Functor, Args ...>> // SFINAE can kick in here
> : public std::is_same<R, FunctorReturn<Functor, Args ...>>::type
{};
Run Code Online (Sandbox Code Playgroud)
您可能已经注意到,我正在使用建议的C++ 17 void_t在专业化的模板参数中利用SFINAE.当FunctorReturn收到 …
我正在使用C++ 03方法在编译时检测函数的存在.我必须使用这个方法而不是void_t方法,即使我使用C++ 14因为我必须支持GCC 4.9,并且在使用void_t方法时出错(奇怪的是只有Ubuntu 14的GCC 4.9有这个问题,而不是Fedora的,但它在GCC5 + AFAICT中全面修复.
具体来说,我正在检查是否存在,operator<<(std::ostream&, const T&)以便我可以使用任何类型的漂亮打印功能.当函数被调用时,如果类型支持它,您将获得常规的ostream输出,并且当未定义运算符时,您将收到有关没有实现的回退消息.代码在底部.
到目前为止,这对我来说非常有效,直到我遇到第三方库定义的类型,我无法改变.该类型具有bool和float的隐式转换运算符.这意味着当SFINAE检查完成以查看是否s << t有效时,我得到编译器错误,因为它s << t是不明确的.在这种情况下,我更喜欢它报告没有像普通的实现,而不是尝试选择隐式转换.有没有办法更改SFINAE检查以使其成为可能?我已经检查过,并且使用GCC5的void_t方法看起来像我想要的那样(在下面的代码中注释掉了),但由于上述原因我还不能使用它.
测试用例:
#include <iostream>
#include <typeinfo>
#include <type_traits>
namespace detail {
namespace has_ostream_operator_impl {
typedef char no;
typedef char yes[2];
struct any_t {
template<typename T> any_t( T const& );
};
no operator<<( std::ostream const&, any_t const& );
yes& test( std::ostream& );
no test( no );
template<typename T>
struct has_ostream_operator {
static std::ostream &s;
static T const &t; …Run Code Online (Sandbox Code Playgroud) 我的工作的通用件的(C++ 11)代码是应该一起工作boost::multi_array,Eigen::Matrix和n维阵列中的,可能是其它类型的.在几个点上,我需要访问给定数组类型的元素类型.boost数组包含一个名为的typedef Element,而Eigen数组包含一个名为的typedef Scalar.
我想要的是一个类型特征,它返回给定数组类型的元素类型.不幸的是,我不能只为所有可能的数组类型专门化trait类,因为Eigen使用表达式模板,因此,有无数种类型的特征矩阵.因此,我使用SFINAE和enable_if来实现我的特性.enable_if应该选择的标准是,类型是否具有被调用的typedef Element,还是被调用的类型Scalar.
为此,我实现了类型特征has_element,并has_scalar确定是否存在相应的typedef.我的实现受到关于类型要求的博客文章的启发.
template <class T>
using ToVoid = void;
template <class T, class Enable = void>
struct has_scalar : public std::false_type {};
template <class T>
struct has_scalar<T, ToVoid<typename T::Scalar>> : public std::true_type {};
template <class T, class Enable = void>
struct has_element : public std::false_type {};
template <class T>
struct has_element<T, ToVoid<typename T::Element>> : public std::true_type {};
Run Code Online (Sandbox Code Playgroud)
我们的想法是,false_type如果没有提供typedef …