简体   繁体   English

如何为模板化类型专门化/重载模板函数

[英]How can I specialize/overload a template function for a templated type

I have the following classes: 我有以下课程:

template <class... T>
class thing {};

template <class T>
class container {
    public:
        container() {
            std::cout << "normal constructor" << std::endl;
        }
};

I can write a full specialization for the constructor of container<int> in this way: 我可以用这种方式为container<int>的构造函数编写一个完整的特化:

template <>
container<int>::container() {
    std::cout << "int constructor" << std::endl;
}

I would like to be able to define a similar constructor for container<thing<T>> . 我希望能够为container<thing<T>>定义一个类似的构造函数。 I think what I'm attempting to write is a partial specialization of a template function (which is illegal.) Here is what I'm attempting: 我认为我试图写的是模板函数的部分特化(这是非法的。)这是我正在尝试的:

template <class T>
container<thing<T>>::container() {

}

This does not compile. 这不编译。

I am not entirely sure what the correct way to go about solving this problem is and the lines between what an overload and a specialization are for a template class function are getting blurred. 我不完全确定解决这个问题的正确方法是什么,以及模板类函数的重载和特化之间的界限越来越模糊。 Can this be trivially solved or will it require type_traits ( std::enable_if )? 这可以简单地解决,还是需要type_traits( std::enable_if )? How can I solve this? 我怎么解决这个问题?

You can't partial specialize the constructor but you don't have necessarily to partial specialize the full class. 您不能部分专门化构造函数,但您没有必要部分专门化完整的类。

Can this be trivially solved or will it require type_traits/enable_if? 这可以简单地解决,还是需要type_traits / enable_if? How can I solve this? 我怎么解决这个问题?

Delegating constructors and tag dispatching can work around the limitation. 委派构造函数和标记调度可以解决限制。
It follows a minimal, working example: 它遵循一个最小的工作示例:

#include<iostream>

template <class... T>
class thing {};

template <class T>
class container {
    template<typename>
    struct tag {};

    template<typename U>
    container(int, tag<thing<U>>) {
        std::cout << "thing<U>" << std::endl;
    }

    container(char, tag<T>) {
        std::cout << "normal constructor" << std::endl;
    }

public:
    container(): container(0, tag<T>{}) {}
};

int main() {
    container<int> c1;
    container<thing<int>> c2{};
}

See it on wandbox . wandbox上看到它。


Note that you can easily extend it if you want to have more than two delegating constructors from which to pick the right one up. 请注意,如果您希望有两个以上的委托构造函数,可以从中选择正确的构造函数,则可以轻松扩展它。
As an example: 举个例子:

#include<iostream>

template <class... T>
class thing {};

template<typename> struct tag {};
template<int N> struct prio: prio<N-1> {};
template<> struct prio<0> {};

template <class T>
class container {    
    template<typename U>
    container(prio<2>, tag<thing<U>>) {
        std::cout << "thing<U>" << std::endl;
    }

    container(prio<1>, tag<double>) {
        std::cout << "double" << std::endl;
    }

    container(prio<0>, tag<T>) {
        std::cout << "normal constructor" << std::endl;
    }

public:
    container(): container(prio<2>{}, tag<T>{}) {}
};

int main() {
    container<int> c1;
    container<double> c2;
    container<thing<int>> c3{};
}

See it on wandbox . wandbox上看到它。

You can't partial specialize the constructor but you can partial specialize the full class 你不能部分专门化构造函数,但你可以部分专门化完整的类

template <class T>
class container<thing<T>>
 {
   public: 
      container() { }
 };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM