标签: partial-specialization

部分专业化和友谊

假设你有这样的A类:

template <typename T, typename U>
class A;
Run Code Online (Sandbox Code Playgroud)

和B级这样:

template <typename T>
class B;
Run Code Online (Sandbox Code Playgroud)

现在你想要两个班级成为朋友,当T是同一类型时,这可能吗?

所以例如A<int, long>是朋友,B<int>B<int>朋友在A<int, U>哪里U可以是任何类型.

c++ templates friend partial-specialization

9
推荐指数
0
解决办法
231
查看次数

C++模板:部分模板规范和朋友类

有可能以某种方式使部分模板规范成为朋友类吗?即你认为你有以下模板类

template <class T> class X{
    T t;
};
Run Code Online (Sandbox Code Playgroud)

现在你有部分特化,例如,指针

template <class T> class X<T*>{
    T* t;
};
Run Code Online (Sandbox Code Playgroud)

我想做到的是,每一个可能X<T*>是朋友类X<S>为ANY S.即X<A*>应该是的朋友X<B>.

当然,我想到了X中通常的模板朋友声明:

template <class T> class X{
    template <class S> friend class X<S*>;
}
Run Code Online (Sandbox Code Playgroud)

但是,这不能编译,g ++告诉我这个:

test4.cpp:34:15:错误:' template<class T> class X'的特化必须出现在命名空间范围内

test4.cpp:34:21:错误:部分特化' X<S*>'声明'朋友'

这根本不可能,还是有一些解决方法?

我之所以要问的是,我需要一个构造函数,X<T*>从任意X<S>(S必须是子类型T)创建这个类.

代码如下所示:

template <class T> class X<T*>{
    T* t;

    template<class S>
    X(X<S> x) : t(&(x.t))  {} //Error, x.t …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization template-specialization friend-class

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

使用非推导上下文的部分特化排序

根据[temp.class.order]§14.5.5.2,t在此示例中选择部分特化:

template< typename >
struct s { typedef void v, w; };

template< typename, typename = void >
struct t {};

template< typename c >
struct t< c, typename c::v > {};

template< typename c >
struct t< s< c >, typename s< c >::w > {};

t< s< int > > q;
Run Code Online (Sandbox Code Playgroud)

等效f于此示例中的重载选择:

template< typename >
struct s { typedef void v, w; };

template< typename, typename = void >
struct t {};

template< typename …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization partial-ordering language-lawyer

8
推荐指数
2
解决办法
525
查看次数

模板部分专业化:如何避免代码重复?

当模板完全专用时,不需要复制成员函数.例如,在以下代码中,foo()只写入一次.

#include <iostream>

template<int M>   
class B
{              
public:
    void foo();   
private:
    void header();
};         

template<int M>   
void          
B<M>::foo()
{
    // specialized code:              
    header();
    // generic code:
    std::cout << "M = " << M << std::endl;             
}                   

template<int M>                                                             
void                                                                        
B<M>::header()                                                              
{                                                                           
    std::cout << "general foo()" << std::endl;                              
}                                                                           

template<>                                                                  
void                                                                        
B<2>::header()                                                              
{                                                                           
    std::cout << "special foo()" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是,对于部分特化,有必要复制类定义和所有成员函数.例如:

#include <iostream>

template<int M, int N>
class A
{                  
public:   
    void foo();   
private:
    void header();
};     

template<int …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization

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

确定类型是否为类类型?

在"C++模板 - 完整指南 - 第二版"一书的第19.8.4章中,作者展示了如何在编译时确定类型是否为类类型:

#include <iostream>
#include <type_traits>
using namespace std;

template <typename T, typename = void_t<>>
struct IsClass : false_type { };

template <typename T>
struct IsClass<T, void_t<int T::*>> : true_type { };

int main()
{
    struct S { };
    cout << IsClass<S>::value; // prints 1
}
Run Code Online (Sandbox Code Playgroud)

本段解释了部分特化如何检测类类型:

...只有类类型可以用作指向成员类型的基础.也就是说,在表单的类型构造中X Y::*,Y只能是类类型.以下公式IsClass<T>利用属性(并int任意选择类型X)

我不明白为什么选择int作为X工作,即使我们测试IsClass<>一个S完全没有成员的结构(它也适用于具有其他成员的类类型int)

c++ templates partial-specialization sfinae type-traits

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

双模板方法的部分特化失败

有模板类List.

template <typename Point>
class List
{


    public:
          template <const unsigned short N>
          void load ( const char *file);
          ...
};

template <typename Point>
template <const unsigned short N>
void List <Point>::load ( const char *file)
}
Run Code Online (Sandbox Code Playgroud)

如何专门化N = 2的方法负载?此代码无效...

template <typename Point>
void List <Point> <2>::load ( const char *file)
{
}
Run Code Online (Sandbox Code Playgroud)

而且这段代码也行不通.

template <typename Point>
void List <Point> ::load <2> ( const char *file )
{ 
}

Error 3 error C2768: 'List<Point>::load' : illegal use of explicit template …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization specialization

7
推荐指数
1
解决办法
2921
查看次数

部分模板专业化

我有一个模板类的场景

template<typename X, typename Y>
class Foo
{
 typedef Y::NestedType Bar;

 int A (Bar thing);
 void B();
 int C(X that);

 // other stuff
};
Run Code Online (Sandbox Code Playgroud)

然后我希望A()方法在X是给定类型时具有不同的行为(但是B和C可以保持不变,而实际代码实际上有大约10种其他方法,其中一些方法非常冗长,经常调整..所以我宁愿避免进行全班专业化并复制和粘贴完整的类实现)

我继续写道:

template<typename T>
int Foo<MyType, T>::A(Bar thing);
Run Code Online (Sandbox Code Playgroud)

但是我的编译器(clang 163.7.1)甚至拒绝将其视为任何类型的模板特化.

在我编写代码的方式中是否隐藏了一些语法错误,或者这种编码风格是无效的C++?不幸的是,即使其他编译器确实支持这个成语,我的公司仍然坚持使用clang.

感谢您的帮助.

c++ templates class partial-specialization template-specialization

7
推荐指数
1
解决办法
2100
查看次数

在派生类中执行成员模板类的部分类内特化是否合法

这是这个问题的延续.如果成员类部分特化是这样的,我特别感兴趣:

struct FooParent {
    template <class>
    struct Bar{ };
};

struct Foo: FooParent {
    template <class T>
    struct Bar<T*> {};
};
Run Code Online (Sandbox Code Playgroud)

我知道这可以在命名空间范围内完成:

template <class T>
struct Foo::Bar<T*>{ };
Run Code Online (Sandbox Code Playgroud)

但我也特别感兴趣的是派生类级别的类内部分特化.

clang和gcc在遇到前者时都会抱怨:

clang声明有明确的模板专业化,显然不会发生:

错误:类范围中'Bar'的显式特化

gcc在这里稍微冗长一点,并说成员模板的特化必须在命名空间范围内执行,这显然不是非派生类的情况.

错误:'template struct FooParent :: Bar'的特化必须出现在命名空间范围内

gcc是否在他的错误消息中?

c++ templates partial-specialization template-specialization language-lawyer

7
推荐指数
1
解决办法
515
查看次数

部分模板特化中匹配可变参数模板模板参数的精确规则

在为另一个问题创建这个答案时,我遇到了以下问题。考虑这个程序(godbolt):

#include <variant>
#include <iostream>

template <typename T>
struct TypeChecker {
    void operator()() {
        std::cout << "I am other type\n";
    }
};

template<typename... Ts, template<typename...> typename V>
requires std::same_as<V<Ts...>, std::variant<Ts...>>
struct TypeChecker<V<Ts...>>
{
    void operator()()
    {
        std::cout << "I am std::variant\n";
    }
};

int main()
{
    TypeChecker<std::variant<int, float>>{}();
    TypeChecker<int>{}();
}
Run Code Online (Sandbox Code Playgroud)

输出(也是预期的)如下(使用 clang 14.0.0 以及 gcc 12.1):

I am std::variant
I am other type
Run Code Online (Sandbox Code Playgroud)

然而,如果模板的参数列表中的三个点被删除,就像这样(整个程序运行在godbolt上):

template<typename... Ts, template<typename> typename V>
Run Code Online (Sandbox Code Playgroud)

,那么 clang 和 gcc 的输出是不同的。clang …

c++ templates partial-specialization template-templates language-lawyer

7
推荐指数
1
解决办法
257
查看次数

成员函数的部分模板专业化:"原型不匹配"

我试图部分特化一个未模板类的模板化成员函数:

#include <iostream>

template<class T>
class Foo {};

struct Bar {

  template<class T>
  int fct(T);

};

template<class FloatT>
int Bar::fct(Foo<FloatT>) {}


int main() {
  Bar bar;
  Foo<float> arg;
  std::cout << bar.fct(arg);
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

c.cc:14: error: prototype for ‘int Bar::fct(Foo<FloatT>)’ does not match any in class ‘Bar’
c.cc:9: error: candidate is: template<class T> int Bar::fct(T)
Run Code Online (Sandbox Code Playgroud)

如何修复编译器错误?

c++ templates partial-specialization template-specialization

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