标签: enable-if

使用嵌套类的奇怪enable_if行为(MSVC编译器错误或功能?)

经过一段时间的调试后,我使用enable_if跟踪了出现问题的原因以及一些意外的模板专业化结果:

以下代码使Visual Studio 2010(和2008)在DoTest()中的声明失败,而在g ++ 3.4.5中则没有。但是,当我从SomeClass中删除模板或将my_condition移出SomeClass的范围时,它也可以在MSVC中使用。

这段代码是否有问题(至少部分地)解释了此行为,或者这是MSVC编译器中的错误?

(使用此示例代码,对于boost和c ++ 0x stl版本是相同的)

#include <cassert>
#include <boost\utility\enable_if.hpp>

template <class X>
class SomeClass {
public:
    template <class T>
    struct my_condition {
        static const bool value = true;
    };

    template <class T, class Enable = void> 
    struct enable_if_tester { 
        bool operator()() { return false; }
    };

    template <class T>
    struct enable_if_tester<T, typename boost::enable_if< my_condition<T> >::type> { 
        bool operator()() { return true; }
    };

    template <class T>
    void DoTest() …
Run Code Online (Sandbox Code Playgroud)

c++ templates nested-class visual-studio enable-if

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

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

基于类模板参数的Specialize C++成员函数

我有一个带有模板参数的类,它应该决定它包含哪两种数据样式.基于该参数,我想以两种不同的方式实现成员函数.我尝试使用Boost Enable-If,但没有成功.这是我最惊讶的代码版本不起作用:

#include <boost/utility/enable_if.hpp>
enum PadSide { Left, Right };
template <int> struct dummy { dummy(int) {} };

template <PadSide Pad>
struct String
{
    typename boost::enable_if_c<Pad ==  Left, void>::type
        getRange(dummy<0> = 0) {}
    typename boost::enable_if_c<Pad == Right, void>::type
        getRange(dummy<1> = 0) {}
};

int main()
{
    String<Left> field;
    field.getRange();
}
Run Code Online (Sandbox Code Playgroud)

为此,g ++ 4.6.0说:

no type named ‘type’ in ‘struct boost::enable_if_c<false, void>’
Run Code Online (Sandbox Code Playgroud)

当然,第二次重载应该不起作用,但是由于SFINAE,它应该被忽略.如果我删除虚函数参数,g ++会这样说:

‘typename boost::enable_if_c<(Pad == Right), void>::type
    String<Pad>::getRange()‘
cannot be overloaded with
‘typename boost::enable_if_c<(Pad == Left), void>::type
    String<Pad>::getRange()‘
Run Code Online (Sandbox Code Playgroud)

这就是为什么我把伪参数放在那里 …

c++ templates boost overloading enable-if

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

enable_if类型不是某个模板类

TLDR:见最后一段.

我有operator&几个模板类的定义,如下所示:

template <typename T>
struct Class {
    Class(T const &t) { }
};

template <typename T_Lhs, typename T_Rhs>
struct ClassAnd {
    ClassAnd(T_Lhs const &lhs, T_Rhs const &rhs) { }
};

template <typename T, typename T_Rhs>
ClassAnd<Class<T>, T_Rhs> operator&(Class<T> const &lhs, T_Rhs const &rhs) {
    return ClassAnd<Class<T>, T_Rhs>(lhs, rhs);
}

template <typename T0, typename T1, typename T_Rhs>
ClassAnd<ClassAnd<T0, T1>, T_Rhs> operator&(ClassAnd<T0, T1> const &lhs, T_Rhs const &rhs) {
    return ClassAnd<ClassAnd<T0, T1>, T_Rhs>(lhs, rhs);
}

int main() {
    Class<int> …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading sfinae enable-if

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

如何使用std :: enable_if条件本身取决于另一个条件?

我有一种情况,我需要区分两个重载,比如说foo,使用std::enable_if.赋予std::enable_if自身的条件取决于模板参数的依赖类型foo.

表达此用法的最佳方式是什么std::enable_if

以下测试代码是我目前所拥有的.我意识到除了std::enable_if在测试代​​码中实现我想要的行为之外,还有更好的方法.但是,以下是我自己需要的用例的简化版本std::enable_if.

#include <type_traits>
#include <cassert>

struct bar
{
  using baz = int;
};

template<class T> struct is_bar : std::false_type {};
template<> struct is_bar<bar> : std::true_type {};

template<class Bar>
struct baz_type
{
  using type = typename Bar::baz;
};


template<class T>
typename std::enable_if<
  std::is_integral<
    typename baz_type<T>::type
  >::value,
  int
>::type
  foo(T x)
{
  return 7;
}

template<class T>
typename std::enable_if<
  !is_bar<T>::value,
  int
>::type
  foo(T x)
{
  return …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming enable-if c++11

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

需要帮助来理解具有复杂typename参数的模板函数

我正在研究Stroustroup的书"C++编程第4版".而我正试图在矩阵设计上遵循他的例子.

他的矩阵类很大程度上依赖于模板,我尽力把它们搞清楚.这是此矩阵的辅助类之一

Matrix_slice是Matrix实现的一部分,它将一组下标映射到元素的位置.它使用了广义切片的思想(§40.5.6):

template<size_t N>
struct Matrix_slice {
    Matrix_slice() = default; // an empty matrix: no elements
    Matrix_slice(size_t s, initializer_list<size_t> exts); // extents
    Matrix_slice(size_t s, initializer_list<size_t> exts, initializer_list<siz e_t> strs);// extents and strides
    template<typename... Dims> // N extents
    Matrix_slice(Dims... dims);


    template<typename... Dims,
    typename = Enable_if<All(Convertible<Dims,size_t>()...)>>
    size_t operator()(Dims... dims) const; // calculate index from a set of    subscripts

    size_t size; // total number of elements
    size_t start; // star ting offset
    array<size_t,N> extents; // number of elements in each dimension
    array<size_t,N> …
Run Code Online (Sandbox Code Playgroud)

c++ metaprogramming variadic-functions enable-if variadic-templates

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

为什么SFINAE(enable_if)从类内部定义而不是外部工作

在过去的几个小时里,我一直在努力解决非常奇怪的问题(在我刚接触SFINAE并解决了5-6个其他问题之后)。基本上,在以下代码中,我希望可以f()处理所有可能的模板实例化,但是g()仅在N == 2以下情况下可用:

#include <type_traits>
#include <iostream>

template<typename T, int N>
class A
{
public:
    void f(void);
    void g(void);
};

template<typename T, int N>
inline void A<T, N>::f()
{
    std::cout << "f()\n";
}

template<typename T, int N, typename std::enable_if<N == 2, void>::type* = nullptr>
inline void A<T, N>::g()
{
    std::cout << "g()\n";
}

int main(int argc, char *argv[])
{
    A<float, 2> obj;
    obj.f();
    obj.g();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试对其进行编译时,我得到一个关于3个模板参数而不是2个模板参数的错误。然后,经过一番尝试,我决定将g()内部的定义移到其A自身的定义内,如下所示:

#include <type_traits> …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization sfinae enable-if

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

使用std :: enable_if和sizeof时未定义的类型.(视觉工作室2017)

如果具有默认模板参数的类型具有某些属性,那么当我编译时间测试时,我得到的似乎是Visual Studio错误.在下面的最小例子中我使用std::is_integer.

使用Visual Studio 2017编译以下程序时

#include <type_traits>
#include <utility>
#include <algorithm>

template<typename U,
    typename Enabled = typename std::enable_if<std::is_integral<U>::value>::type>
    struct wrapper
{
};

template<typename U, typename storage_type>
using is_small = std::is_void<typename std::enable_if <
(sizeof(wrapper<U, char>) <= sizeof(storage_type))
>::type>;
Run Code Online (Sandbox Code Playgroud)

我得到以下输出

1>bug.cpp(13): error C2027: use of undefined type 'wrapper<U,char>'
1>bug.cpp(13): note: see declaration of 'wrapper<U,char>'
Run Code Online (Sandbox Code Playgroud)

相同的程序在g ++ 6.1 编译.

Enable删除默认参数时,程序会在Visual Studio上编译.另外,当我sizeof(...)<=sizeof(...)在以下模板成员函数中执行相同的测试时,程序编译正常(is_small删除).

struct c
{
    template<typename U, typename storage_type>
    typename std::enable_if<(sizeof(wrapper<U, char>) <= sizeof(storage_type))>::value
        foo(U u, …
Run Code Online (Sandbox Code Playgroud)

c++ sizeof visual-studio enable-if

5
推荐指数
0
解决办法
178
查看次数

推荐的模拟概念和约束的方法是什么?

在介绍概念和约束之前,有几种方法可以模拟此编译时检查。以“ order()”功能为例:(如何在LessThanComparable没有概念或约束的情况下实施是另一回事)

  • 使用 static_assert

    template <typename T, typename U>
    void order(T& a, U& b)
    {
        static_assert(LessThanComparable<U,T>, "oh this is not epic");
        if (b < a)
        {
            using std::swap;
            swap(a, b);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这种方法不适用于函数重载。

  • 使用 typename = enable_if

    template <typename T, typename U,
        typename = std::enable_if_t<LessThanComparable<U,T>>>>
    void order(T& a, U& b)
    {
        if (b < a)
        {
            using std::swap;
            swap(a, b);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    如果过分“聪明”的家伙用手指定了第三个参数怎么办?

  • 使用enable_if的函数原型:

    template <typename T, typename U>
    std::enable_if_t<LessThanComparable<U,T>>, void> order(T& a, U& b) …
    Run Code Online (Sandbox Code Playgroud)

c++ sfinae enable-if template-meta-programming c++11

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

为什么“专业辩论”必须无效?

因此,在这个传奇中还有另一个问题。Guillaume Racicot足够出色,可以为我提供另一个解决方法,因此这是我基于以下问题得出的代码:

struct vec
{
    double x;
    double y;
    double z;
};

namespace details
{
template <typename T>
using subscript_function = double(*)(const T&);

template <typename T>
constexpr double X(const T& param) { return param.x; }

template <typename T>
constexpr double Y(const T& param) { return param.y; }

template <typename T>
constexpr double Z(const T& param) { return param.z; }
}

template <typename T, typename = void>
constexpr details::subscript_function<T> my_temp[] = { &details::X<T>, &details::Y<T> }; …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-specialization enable-if template-variables

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