标签: partial-specialization

专门化成员模板而不专门化其父模板

我有一个嵌套在另一个模板中的类模板.部分特殊化很简单:我只是template< … >在其父级中声明另一个块.

但是,我需要另一个部分特化,恰好指定其所有本地模板参数.这使它成为一个明确的专业化.无论出于何种原因,显式特化都必须在命名空间范围内.要在父类之外声明它,必须提名父级,这需要非空的模板参数列表.这意味着部分专业化.部分专业化我正在做的事情,它应该在任意外部范围内工作.但GCC和Comeau都无法使用部分特化形式参数识别父提名中的模板参数.

template< class X > struct A {
    template< class Y > struct B; // initial declaration OK

    template< class Z >
    struct B< A< Z > > {}; // partial OK as long as there's a local arg

    template<> // ERROR: this syntax triggers explicit specialization
    struct B< int > {};
};

template<> // ERROR: can't nest template<>s here (why?)
template< class X > // ERROR: can't deduce X from type of …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization

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

如何只对模板类的某些成员进行专门化?

码:

template<class T>
struct A {
  void f1() {};
  void f2() {};

};

template<>
struct A<int> {
  void f2() {};
};


int main() {
  A<int> data;
  data.f1();
  data.f2();
};
Run Code Online (Sandbox Code Playgroud)

错误:

test.cpp: In function 'int main()':
test.cpp:16: error: 'struct A<int>' has no member named 'f1'
Run Code Online (Sandbox Code Playgroud)

基本上,我只想专门化一个函数并使用其他函数的通用定义.(在实际代码中,我有许多我不想专门研究的函数).

这该怎么做?谢谢!

c++ templates partial-specialization template-specialization

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

具有非类型参数的成员函数的部分特化

我有一个带有类型和非类型模板参数的模板类.我想专门化一个成员函数,我发现的是,如下例所示,我可以完全专业化.

template<typename T, int R>
struct foo
{
    foo(const T& v) :
        value_(v)
    {}

    void bar()
    {
        std::cout << "Generic" << std::endl;
        for (int i = 0; i < R; ++i)
            std::cout << value_ << std::endl;
    }

    T value_;
};

template<>
void foo<float, 3>::bar()
{
    std::cout << "Float" << std::endl;
    for (int i = 0; i < 3; ++i)
        std::cout << value_ << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是这种部分特化不会编译.

template<int R>
void foo<double, R>::bar()
{
    std::cout << "Double" << std::endl;
    for (int i …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization template-specialization

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

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

以下代码

#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
查看次数

如何为所有派生类型部分专门化类模板?

我想部分专门化一个现有的模板,我无法改变(std::tr1::hash)基类和所有派生类.原因是我使用奇怪的重复模板模式进行多态,并且哈希函数在CRTP基类中实现.如果我只想部分专门用于CRTP基类,那么它很简单,我可以写:


namespace std { namespace tr1 {

template <typename Derived>
struct hash<CRTPBase<Derived> >
{
    size_t operator()(const CRTPBase<Derived> & base) const 
    { 
        return base.hash(); 
    }
};

} }
Run Code Online (Sandbox Code Playgroud)

但是这种专门化只与实际的派生类不匹配CRTPBase<Derived>.我想要的是一种编写部分特化的方法,Derived当且仅当它来源于CRTPBase<Derived>.我的伪代码是


namespace std { namespace tr1 {

template <typename Derived>
struct hash<typename boost::enable_if<std::tr1::is_base_of<CRTPBase<Derived>, Derived>,
    Derived>::type>
{
    size_t operator()(const CRTPBase<Derived> & base) const 
    { 
        return base.hash(); 
    }
};

} }
Run Code Online (Sandbox Code Playgroud)

......但是,这并不工作,因为编译器不能告诉大家,enable_if<condition, Derived>::typeDerived.如果我可以更改std::tr1::hash,我只需添加另一个虚拟模板参数boost::enable_if,如enable_if文档所建议的那样,但这显然不是一个很好的解决方案.有没有解决这个问题的方法?我是否必须在每个unordered_set或 …

c++ partial-specialization derived-class crtp

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

指针作为模板参数?

我有一个容器类,我们称之为

template <class T> CVector { ... } 
Run Code Online (Sandbox Code Playgroud)

当T是指针类型时,我想对这个类做一些不同的事情,例如:

template <class T*> CVector< SomeWrapperClass<T> >;
Run Code Online (Sandbox Code Playgroud)

SomeWrapperClass期望指向的东西的类型作为其参数.不幸的是,这种语法不太适用,并且通过一些挖掘,我还没有找到一种很好的方法来获得这样的工作.

为什么这样?我想在一个非常大的应用程序中更改我们的一些容器如何工作,当他们专门的类型是指针而非指针 - 理想情况下,我想这样做而不改变〜1,000个地方在代码中有像CVector<Object*>vs CVector<int>或某些东西这样的东西- 并且玩具有局部特化的游戏似乎是要走的路.

我在这里破解吗?

c++ templates partial-specialization

9
推荐指数
3
解决办法
3万
查看次数

部分专业化和友谊

假设你有这样的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>
void calculator<std::complex<T>>::myMin();
Run Code Online (Sandbox Code Playgroud)

但也许只是给它一个提示?明确表示它是部分专业化。

template < , class T>
void calculator<std::complex<T>>::myMin();
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization

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

部分模板特化与不匹配的`int`和`size_t`不编译

参考以下代码

#include <utility>
#include <cassert>

template <typename T>
struct Wot;
template <int... ints>
struct Wot<std::index_sequence<ints...>> {};

int main() {
    assert(sizeof(Wot<std::index_sequence<1, 2, 3>>) == 1);
}
Run Code Online (Sandbox Code Playgroud)

这适用于clang但不适用于gcc,当我std::size_t在索引序列中更改要接受的部分特化的类型时,它可以工作.

谁是对的?Clang还是gcc?


在此处查看此操作https://wandbox.org/permlink/5YkuimK1pH3aKJT4

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

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

类专业化中的 clang/gcc 不一致

我在尝试为C++17 中的自定义类专门化tuple_size/tuple_element以进行结构化绑定时遇到了这个问题。

下面的代码在 GCC 中编译,但不在 clang 中(两个主干版本,见下面的链接)。

#include <type_traits>

template<typename T, typename... Ts>
using sfinae_t = T;

template<typename T, bool... Bs>
using sfinae_v_t = sfinae_t<T, typename std::enable_if<Bs>::type...>;

template <typename T>
struct Test;

template <typename T>
struct Test<sfinae_v_t<T, std::is_integral_v<T>>> {};

void f() {
    Test<int> t;
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/ztuRSq

这是 clang 提供的错误:

<source>:13:8: error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list

struct Test<sfinae_v_t<T, std::is_integral<T>::value>> {};

       ^ …
Run Code Online (Sandbox Code Playgroud)

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

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