为类模板专门化添加方法

时间:2019-02-24 10:51:46

标签: c++ templates stl template-specialization

我想实现STL中存在的行为:当我们查看向量容器时,众所周知它具有vector<bool>专门化,它添加了方法flip()

是否可以实现这样的类扩展,而无需将整个类复制为特化对象并在其主体中添加新方法?

2 个答案:

答案 0 :(得分:1)

我想您可以编写专业化名称,以便它从通用版本继承。

通过示例:假设您有一个struct foo,其类型和值(带有默认值)模板参数;假设它有一些方法(在下面的示例中为bar()

template <typename, bool = true>
struct foo 
 { void bar () {}; };

,并假设您希望使用相同的方法和另外的boolbaz()(作为模板类型)的专业化;您可以按照以下常规版本继承foo<bool>

template <>
struct foo<bool> : public foo<bool, false>
 { void baz () {}; };

您可以验证

   foo<int>   fi;

   fi.bar();   // compile
   //fi.baz(); // compilation error

   foo<bool>  fb;

   fb.bar();  // compile
   fb.baz();  // compile

答案 1 :(得分:1)

您可以SFINAE的“专业化”方法

**MODELS.PY**

class User(auth.models.User,auth.models.PermissionsMixin):

    def __str__(self):
        return "@{}".format(self.username)

    def get_absolute_url(self):
        return reverse("accounts:login")

class Group(models.Model):
    name = models.CharField(max_length = 255,unique = True)
    slug = models.SlugField(allow_unicode = True,unique = True)
    description = models.TextField(default = '')
    members = models.ManyToManyField(User,related_name = "group")

    def save(self,*args,**kwargs):
        self.slug = slugify(self.name)
        super(Group,self).save(*args,**kwargs)

    def get_absolute_url(self):
        return reverse('groups:single',kwargs = {'slug':self.slug})

    def __str__(self):
        return self.name

class Post(models.Model):
    message = models.TextField()
    created_at = models.DateField(auto_now = True)
    user = models.ForeignKey(User,related_name='posts',on_delete=models.CASCADE)
    group = models.ForeignKey(Group,related_name='posts',on_delete=models.CASCADE)

    def __str__(self):
        return self.message

    def get_absolute_url(self):
        return reverse('posts:single',kwargs = {'username':self.user.username,'pk':self.pk})

    class Meta():
        ordering = ['-created_at']

**Views.py**

class UserPosts(generic.ListView):
    model = models.Post
    template_name = 'posts/user_post_list.html'

    def get_query_set(self):
        if self.request.user.is_authenticated:
            self.username = get_object_or_404(User,username__iexact=self.request.user.username)
            return models.Post.objects.filter(user=self.username)
        else:
            raise Http404

**Html Code**
  <div class="col-md-4">
    {% for post in post_list %}
      <p> {{ post.user.username }} </p>
    {% endfor %}
 </div>

C ++ 20将允许更好的语法:

template <typename T>
class C
{
public:
    // Common code...

    template <typename U = T, std::enable_if_t<std::is_same<bool, U>::value, bool> = false>
    void only_for_bool() {/*..*/}
};