标签: class-template

约束函数会允许模板参数取决于函数参数吗?

在C ++ 17中,此代码是非法的:

constexpr int foo(int i) {
    return std::integral_constant<int, i>::value;
}
Run Code Online (Sandbox Code Playgroud)

这是因为即使foo可以在编译时进行评估,编译器仍然需要产生指令以在运行时执行它,从而使模板实例化成为不可能。

在C ++ 20中,我们将具有consteval需要在编译时评估的函数,因此应删除运行时约束。这是否意味着该代码将是合法的?

consteval int foo(int i) {
    return std::integral_constant<int, i>::value;
}
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer class-template constexpr c++20

55
推荐指数
3
解决办法
1521
查看次数

没有 bool 数组的类模板特化?

根据https://en.cppreference.com/std::vector<bool>具有类模板专业化,而std::array<bool, N>没有。不提供的原因有哪些?

c++ stdvector template-specialization class-template stdarray

27
推荐指数
4
解决办法
1205
查看次数

为什么这个调用swap()模棱两可?

以下程序

#include <algorithm>
#include <utility>
#include <memory>

namespace my_namespace
{


template<class T>
void swap(T& a, T& b)
{
  T tmp = std::move(a);
  a = std::move(b);
  b = std::move(tmp);
}

template<class T, class Alloc = std::allocator<T>>
class foo {};

}

int main()
{
  my_namespace::foo<int> *a, *b;

  using my_namespace::swap;

  swap(a,b);

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

导致两者g++clang在我的系统上发出以下编译器错误:

$ clang -std=c++11 swap_repro.cpp -I.
swap_repro.cpp:28:3: error: call to 'swap' is ambiguous
  swap(a,b);
  ^~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/algorithmfwd.h:571:5: note: candidate function [with _Tp = my_namespace::foo<int, std::allocator<int> > …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces class-template name-lookup argument-dependent-lookup

23
推荐指数
2
解决办法
1643
查看次数

带有条件类型名的模板类

我想有一个模板类(如float/double类型),但我使用Nvidia的CUDAOptix公司和有多个其他类型(例如float2double2float3,...)依赖于所选择的模板类型。

像这样的东西:

#include <optixu/optixu_vector_types.h>
#include <type_traits>

template <class T>
class MyClass 
{
   MyClass()
   {
      if (std::is_same<T, float>::value) 
      {
         typedef optix::float2 T2;
      }
      else if (std::is_same<T, double>::value)
      {
         typedef optix::double2 T2;
      }

      T2 my_T2_variable;
   }

   void SomeFunction() 
   { 
      T2 another_T2_variable; 
   };
};
Run Code Online (Sandbox Code Playgroud)

我现在的解决方案是有多个模板参数MyClass<T,T2,T3> my_object;,但这似乎有太多的开销和混乱。有没有办法使用上述所需的单个模板参数实现相同的目标?

c++ templates class class-template c++11

19
推荐指数
3
解决办法
1191
查看次数

类模板的嵌套模板参数推断不起作用

这个Q&A中,我编写了一个小包装类,它提供了对范围的反向迭代器访问,依赖于类模板的c ++ 1z语言特征模板参数推导(p0091r3,p0512r0)

#include <iostream>
#include <iterator>
#include <vector>

template<class Rng>
class Reverse
{
    Rng const& rng;    
public:    
    Reverse(Rng const& r) noexcept
    : 
        rng(r)
    {}

    auto begin() const noexcept { using std::end; return std::make_reverse_iterator(end(rng)); }
    auto end()   const noexcept { using std::begin; return std::make_reverse_iterator(begin(rng)); }
};

int main()
{
    std::vector<int> my_stack;
    my_stack.push_back(1);
    my_stack.push_back(2);
    my_stack.puhs_back(3);

    // prints 3,2,1
    for (auto const& elem : Reverse(my_stack)) {
        std::cout << elem << ',';    
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,执行嵌套应用程序Reverse不会产生原始迭代顺序 …

c++ templates class-template argument-deduction c++17

13
推荐指数
2
解决办法
552
查看次数

以下程序是否应按标准编译?

在我发现MSVC和GCC(也可能是clang)之间在编译和链接相同代码时的不兼容之后,我很好奇这个程序是否实际编译和链接,因此它是MSVC中的错误(报告链接器错误)或应该我用不同的方式写它.该计划包括3个文件:

template <typename T>
struct A
{
    void func() {};
};

template <>
void A<int>::func ();
Run Code Online (Sandbox Code Playgroud)

A.cpp:

#include "C.h"
int main()
{
    A<int> x;
    x.func();
}
Run Code Online (Sandbox Code Playgroud)

B.cpp:

#include "C.h"
template <>
void A<int>::func()
{
}
Run Code Online (Sandbox Code Playgroud)

MSVC产生的链接器错误是:

A.obj:错误LNK2019:未解析的外部符号"public:void __thiscall A :: func(void)"

所以基本上它决定不在定义中创建符号B.cpp.让我强烈怀疑它是一个错误的东西是移动func结构定义的非特定定义,甚至将它放在特化声明之上使程序成功,但我想确定.

所以我的问题是 - 是否应该通过符合标准的编译器/链接器编译和链接此程序而不会出错?

c++ template-specialization visual-c++ class-template

10
推荐指数
1
解决办法
195
查看次数

g ++ c ++ 17类模板参数推导不适用于非常具体的情况

我有以下代码:

template <class T>
class lit {
public:
    lit(T l) : val(l) {}
    T val;
};

template <class T>
class cat {
public:
    cat(lit<T> const& a, lit<T> const& b) : a(a), b(b) {}
    lit<T> const& a;
    lit<T> const& b;
};

template <class T>
cat<T> operator+(lit<T> const& a, lit<T> const& b) {
    return cat(a, b);
}

int main() {
    auto r1 = cat((lit      ('b')),  lit('d')); // compiles
    auto r2 =     (lit      ('b')) + lit('d') ; // doesn't compile
    auto r3 = …
Run Code Online (Sandbox Code Playgroud)

c++ templates class-template template-argument-deduction c++17

10
推荐指数
2
解决办法
421
查看次数

有没有CRTP没有编译时间检查?

我试图使用奇怪的重复模板模式实现静态多态性,当我注意到static_cast<>,通常在编译时检查一个类型是否实际可以转换为另一个,在基类声明中错过了一个错误,允许代码向下转换基础与其中一个兄弟姐妹同课:

#include <iostream>

using namespace std;

template< typename T >
struct CRTP
{
    void do_it( )
    {
        static_cast< T& >( *this ).execute( );
    }
};

struct A : CRTP< A >
{
    void execute( )
    {
        cout << "A" << endl;
    }
};

struct B : CRTP< B >
{
    void execute( )
    {
        cout << "B" << endl;

    }
};

struct C : CRTP< A > // it should be CRTP< C >, but typo …
Run Code Online (Sandbox Code Playgroud)

c++ static-cast static-polymorphism class-template

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

避免默认模板中的尖括号

如果我有一个默认模板类型的模板类,但我必须写模板尖括号.有可能避免这种情况吗?

例:

template <typename T=int>
class tt {
public:
  T get() { return 5; }
};

...

tt<> t;  // how to avoid <>
std::cout << t.get() << std::endl;
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已通过单独的命名空间完成此操作并重新声明该类:

namespace detail_ {
template <typename T=int>
class tt {
public:
  T get() { return 5; }
};
}

class tt : public detail_::tt {}

...

tt t;
std::cout << t.get() << std::endl;
Run Code Online (Sandbox Code Playgroud)

问题是,如果我想使用其他类型的类,我必须去名称空间detail_.有没有其他解决方案,我还没有看到.

c++ templates coding-style class-template

8
推荐指数
3
解决办法
1871
查看次数

具有模板类型的C ++ 20指定的初始值设定项

指定的初始化程序(C ++ 20)应该如何与CTAD一起使用?

这段代码在gcc9.2中可以正常工作,但在clang8中失败

template <typename int_t=int, typename float_t=float>
struct my_pair {
    int_t   first;
    float_t second;
};

template<typename ... ts>
my_pair(ts...) -> my_pair<ts...>;

int main() {
    my_pair x{.first = 20, .second = 20.f};
    static_assert( std::is_same_v<decltype(x.first), int> );
    static_assert( std::is_same_v<decltype(x.second), float> );
}
Run Code Online (Sandbox Code Playgroud)

这应该是有效的吗?

参见https://godbolt.org/z/KtNI43上的示例

c++ designated-initializer class-template argument-deduction c++20

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