标签: partial-specialization

获取没有显式特征的整数模板参数的有符号/无符号变体

我想定义一个模板类,其模板参数将始终是一个整数类型.该类将包含两个成员,一个是类型,另一个是类型T的无符号变体T- 即if T == int,then T_Unsigned == unsigned int.我的第一直觉是这样做:

template <typename T> class Range {
    typedef unsigned T T_Unsigned; // does not compile
public:
    Range(T min, T_Unsigned range);
private:
    T m_min;
    T_Unsigned m_range;
};
Run Code Online (Sandbox Code Playgroud)

但它不起作用.然后我考虑使用部分模板专业化,如下所示:

template <typename T> struct UnsignedType {}; // deliberately empty
template <> struct UnsignedType<int> {
    typedef unsigned int Type;
};

template <typename T> class Range {
    typedef UnsignedType<T>::Type T_Unsigned;
    /* ... */
};
Run Code Online (Sandbox Code Playgroud)

只要您UnsignedType每个整数类型进行部分专门化,这都可以.这是一些额外的复制粘贴工作(削减明智地使用宏),但可以使用. …

c++ unsigned templates partial-specialization traits

19
推荐指数
1
解决办法
2616
查看次数

模板部分特化用于积分非类型参数和非积分非类型,g ++和clang之间的区别

以下是一个简单的模板部分特化:

// #1
template <typename T, T n1, T n2>
struct foo { 
    static const char* scenario() {
        return "#1 the base template";
    }
};

// #2
// partial specialization where T is unknown and n1 == n2
template <typename T, T a>
struct foo<T, a, a> { 
    static const char* scenario() {
        return "#2 partial specialization";
    }
};
Run Code Online (Sandbox Code Playgroud)

下面的主要内容在g ++(6.1)和clang ++(3.8.0)上有不同的结果:

extern const char HELLO[] = "hello";
double d = 2.3;

int main() {
    cout <<   foo<int, 1, 2> …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization template-specialization

19
推荐指数
1
解决办法
400
查看次数

模板参数包中的6个点是什么?

在看这个问题的时候,我发现自己在cpp参考站点,我发现了一个奇怪的新手语法:

template<class Ret, class... Args>
struct is_function<Ret(Args......)volatile &&> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)

是的,6个点!最初我认为这是一个拼写错误,但在再次检查libstdc ++ 之后,例如在第444行:

template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes......) volatile &&> : public true_type { };
Run Code Online (Sandbox Code Playgroud)

这是一个有效的语法吗?点点,用于打包和解包参数包?6个点做什么?

c++ partial-specialization variadic-templates c++11 c++14

15
推荐指数
2
解决办法
2912
查看次数

模板部分特化可以缩小 C++ 中的参数类型吗?

在下一个程序中,结构模板A<int>有一个专门化A<char>

template <int>
struct A { constexpr operator int() { return 1; } };

template <char c>
struct A<c> { constexpr operator int() { return 2; } };

int main() {
    static_assert( A<1000>{} == 1 ); //ok in Clang and GCC
    static_assert( A<1>{} == 2 ); //ok in Clang only
}
Run Code Online (Sandbox Code Playgroud)
  • Clang 接受整个程序。
  • GCC 接受专业化定义,但在A<1>{}.
  • MSVC 抱怨这种专业化:
error C2753: 'A<c>': partial specialization cannot match argument list for primary template
Run Code Online (Sandbox Code Playgroud)

演示: https: //gcc.godbolt.org/z/Ef95jv5E5

这里是哪个编译器?

c++ templates partial-specialization language-lawyer

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

部分模板专业化模糊

我不明白为什么主要陈述含糊不清.

template<class T, class U, int I> struct X
{ void f() { cout << "Primary template" << endl; } };


template<class T, int I> struct X<T, T*, I>
{void f() { cout << "Partial specialization 1" << endl;}};

template<class T, class U, int I> struct X<T*, U, I>
{void f() { cout << "Partial specialization 2" << endl;}};

template<class T> struct X<int, T*, 10>
{void f() { cout << "Partial specialization 3" << endl;}};

template<class T, class U, int …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization specialization template-specialization

13
推荐指数
1
解决办法
1768
查看次数

自由功能的部分模板专业化 - 最佳实践

正如大多数C++程序员应该知道的那样,不允许对自由函数进行部分模板特化.例如,以下是非法的C++:

template <class T, int N>
T mul(const T& x) { return x * N; }

template <class T>
T mul<T, 0>(const T& x) { return T(0); }

// error: function template partial specialization ‘mul<T, 0>’ is not allowed
Run Code Online (Sandbox Code Playgroud)

然而,类/结构的模板偏特允许的,并且可以被利用来模仿的自由功能模板偏特的功能.例如,最后一个示例中的目标目标可以通过以下方式实现:

template <class T, int N>
struct mul_impl
{
    static T fun(const T& x) { return x * N; }
};

template <class T>
struct mul_impl<T, 0>
{
    static T fun(const T& x) { return T(0); }
};

template …
Run Code Online (Sandbox Code Playgroud)

c++ partial-specialization non-member-functions

12
推荐指数
1
解决办法
4377
查看次数

什么是支持"部分专业化"的其他语言?

部分模板专业化是C++中通用编程最重要的概念之一.例如:实现通用交换功能:

template <typename T>
void swap(T &x, T &y) {
  const T tmp = x;
  y = x;
  x = tmp;
}
Run Code Online (Sandbox Code Playgroud)

专门用于支持O(1)交换的向量:

template <typename T, class Alloc>
void swap(vector<T, Alloc> &x, vector<T, Alloc> &y) { x.swap(y); }
Run Code Online (Sandbox Code Playgroud)

因此,当您在泛型函数中调用swap(x,y)时,总能获得最佳性能;

非常感谢,如果您可以在替代语言中发布等效语言(或语言的部分专业化的规范示例,如果语言不支持交换概念).

编辑:所以看起来许多回答/评论的人真的不知道什么是部分专业化,而且通用交换示例似乎妨碍了某些人的理解.一个更一般的例子是:

template <typename T>
void foo(T x) { generic_foo(x); }
Run Code Online (Sandbox Code Playgroud)

部分专业化将是:

template <typename T>
void foo(vector<T> x) { partially_specialized_algo_for_vector(x); }
Run Code Online (Sandbox Code Playgroud)

完整的专业化将是:

void foo(vector<bool> bitmap) { special_algo_for_bitmap(bitmap); }
Run Code Online (Sandbox Code Playgroud)

为什么这很重要?因为你可以在泛型函数中调用foo(任何东西):

template <typename T>
void bar(T x) {
  // stuff...
  foo(x);
  // …
Run Code Online (Sandbox Code Playgroud)

language-agnostic generics programming-languages partial-specialization

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

C++模板部分特化 - 仅专门用于一个成员函数

陷入另一个模板问题:

问题:我想在对象是指针的情况下部分地专门化一个容器类(foo),并且我只想专门使用delete-method.应该是这样的:

lib代码

template <typename T>
class foo
{
public:
    void addSome    (T o) { printf ("adding that object..."); }
    void deleteSome (T o) { printf ("deleting that object..."); }
};

template <typename T>
class foo <T *>
{
public:
    void deleteSome (T* o) { printf ("deleting that PTR to an object..."); }
};
Run Code Online (Sandbox Code Playgroud)

用户代码

foo<myclass> myclasses;
foo<myclass*> myptrs;

myptrs.addSome (new myclass());
Run Code Online (Sandbox Code Playgroud)

这导致编译器告诉我myptrs没有一个名为addSome的方法.为什么?

感谢名单.


根据托尼的答案,完全可编辑的东西


LIB

template <typename T>
class foobase
{
public:
    void addSome    (T o) { printf …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization

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

部分特化类的成员定义

我正在尝试定义部分专门化的类模板的成员函数,但是不同的编译器对我可以做什么以及为什么有截然不同的看法。

让我们慢慢来,从适用于所有主要编译器(all = gcc、clang 和 msvc)的东西开始:

#include <concepts>
#include <type_traits>

template <class T>
concept Integer
= std::is_same_v<T,int> || std::is_same_v<T,unsigned int>;

template <class T>
concept FloatingPoint
= std::is_same_v<T,float> || std::is_same_v<T,double>;


template <class T>
struct Foo
{
    T get() {return 0;}
};

template <Integer T>
struct Foo<T>
{
    T get(){ return 0; }
};

template <FloatingPoint T>
struct Foo<T>
{
    T get(){ return 0; }
};

int main()
{
    Foo<char>().get();
    Foo<int>().get();
    Foo<float>().get();
}
Run Code Online (Sandbox Code Playgroud)

Godbolt 上的示例:gccclangmsvc

很酷,但我想将成员函数的声明和定义分开。让我们将定义移到专门的类之一 …

c++ partial-specialization visual-c++ language-lawyer c++-concepts

11
推荐指数
1
解决办法
245
查看次数

可变参数模板的部分特化需要第一个非可变参数模板参数

以下代码

#include <iostream>
#include <utility>

template<typename F, typename... T>
struct Wrapper{ };

template<typename T>
struct is_wrapper : std::false_type {};

template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};

//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};

int main()
{
    Wrapper<int, double> w;

    std::cout << is_wrapper<decltype(w)>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

打印0.但是,如果取消注释中间的两行,则打印1.

为什么不总是打印1?第二部分专业化是否也应该涵盖显然仅由第三(评论)部分专业化所涵盖的案例?

c++ partial-specialization variadic-templates c++11

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