相关疑难解决方法(0)

检查是否存在接受T param的非成员函数

我想检查是否存在接受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中的错误,或者代码是在某个"实现定义"区域中,我不能假设它在所有平台上都有相同的行为?

c++ sfinae c++11

14
推荐指数
1
解决办法
500
查看次数

如何在C++ 11中访问可能不存在的类型别名?

我想写这样的东西:

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.有办法解决这个问题吗?

c++ templates c++11

11
推荐指数
2
解决办法
792
查看次数

static断言模板typename T不完整?

有没有办法在标题中的那个点上使用static_assert类型T 完整?如果有人在他们不应该的地方添加#includes,那么这个想法就会产生编译错误.

相关: 如何写`is_complete`模板?

使用该链接的答案,

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类型"错误,哦.有没有办法断言否定?

c++ templates static-assert incomplete-type

9
推荐指数
1
解决办法
803
查看次数

使用以下has_member函数,SFINAE无法正常工作?

我正在尝试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)

c++ templates sfinae template-specialization c++11

8
推荐指数
1
解决办法
337
查看次数

C++ 11:模板参数中的SFINAE,GCC vs Clang

我想实现一个小的trait类来确定一个类型是否已operator()正确重载,以便我可以查询类似的类型:

FunctorCheck<F, void(int, char)>::value
Run Code Online (Sandbox Code Playgroud)

最初,我对如何从这个问题实现这个问题有了一个想法,但在看了一篇关于TMPCppcon讲座之后,我突然意识到这个问题可以更优雅地解决.这就是我想出来的,它在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收到 …

gcc templates clang sfinae c++11

6
推荐指数
1
解决办法
802
查看次数

在编译时检测运算符而不进行隐式转换

我正在使用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++ gcc sfinae c++11 c++14

5
推荐指数
1
解决办法
440
查看次数

使用enable_if选择特征 - 与clang一起使用,但不与gcc一起使用

我的工作的通用件的(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 …

c++ gcc templates clang c++11

4
推荐指数
1
解决办法
480
查看次数