0

我的目标是能够比较模板,即写这样的东西

template<typename T>
struct template_type;

template<template <typename...> typename TTmpl, typename ...Ts>
struct template_type<TTmpl<Ts...>> { using type = TTmpl; }; // [1] this isn't valid C++

template<typename TRng, typename T>
auto find(TRng&& rng, const T& val)
{
    using TTmpl = typename mcu::template_type<std::remove_const_t<std::remove_reference_t<TRng>>>::type;

    if constexpr (std::is_same_v<TTmpl, std::set>) // [2] this isn't valid C++
    {
        return rng.find(val);
    }
    else
    {
        using namespace std;
        return std::find(begin(rng), end(rng), val);
    }
}

我的第二次尝试是使用别名模板和自定义same函数。就像是:

template<typename T>
struct template_type;

template<template <typename...> typename TTmpl, typename ...Ts>
struct template_type<TTmpl<Ts...>> { template<typename ...Us> using type = TTmpl<Us...>; };

template<template<typename...>typename T1, template<typename...> typename T2>
struct same : std::false_type {};

template<template<typename...>typename T>
struct same<T, T> : std::true_type {};

但这也不起作用。问题是same<std::set, template_type<std::set<int>>::type>::value返回false,即模板类和它的模板别名由于某种原因不同。

我的第三次尝试是写类似的东西,template_type_identity但我不知道应该用什么作为身份:

template<template<typename...> typename T>
struct template_type_identity { using type = ???; }; // I could hardcode some constexpr ids for each template but I wanna generic solution
4

1 回答 1

2

我不确定我是否理解你想要什么,也是因为我会为你的动机案例使用不同的解决方案(sfinae on the presence of member find)。无论如何,如果模板只有类型参数,您可以通过以下方式检查给定类型是否是模板的实例化:

#include <iostream>
#include <type_traits>
#include <set>
#include <vector>

template <template<typename...> typename T, typename C>
struct is_instantiation_of : std::false_type {};

template <template<typename...> typename T,typename ...P>
struct is_instantiation_of< T,T<P...>> : std::true_type {};

int main(){
    std::cout << is_instantiation_of<std::set,std::set<int>>::value;
    std::cout << is_instantiation_of<std::set,std::vector<int>>::value;
}

输出

10
于 2021-07-14T11:54:52.537 回答