检查使用哪个模板参数实例化了类(编译时)

gla*_*des 4 c++ sfinae template-specialization template-meta-programming

我尝试编写一个元函数,只要类的模板参数与给定类型匹配,type_par_same_as它就会进行选择:true_type

演示

#include <type_traits>
#include <concepts>
#include <string>
#include <vector>
#include <cstdio>

template <template <typename...> class Template, typename T>
struct type_par_same_as_impl : std::false_type {};

template <template <typename...> class Template, typename... Args>
struct type_par_same_as_impl<Template<Args...>, Args...> : std::true_type {};

template <template <typename...> class Template, typename... Args>
concept type_par_same_as = type_par_same_as_impl<Template, Args...>::value;

int main()
{

    std::vector<int> vint;
    std::vector<std::string> vstring;
    if constexpr (type_par_same_as<decltype(vint), int>) {
        printf("Vector instantiated with type int!\n");
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的:

<source>:11:56: error: type/value mismatch at argument 1 in template parameter list for 'template<template<class ...> class Template, class T> struct type_par_same_as_impl'
   11 | struct type_par_same_as_impl<Template<Args...>, Args...> : std::true_type {};
      |                                                        ^
<source>:11:56: note:   expected a class template, got 'Template<Args ...>'
Run Code Online (Sandbox Code Playgroud)

我的方法是原始模板模板参数只接受模板的任何专门化,例如std::vector(没有类型)。然后我 SFINAE-out 与模板专业化 Template<Args...> 不匹配的类类型(例如,std::vector<int>如果 int 被给出为Args),并且我应该收到true_type可以完成此操作的所有类类型。但我的逻辑似乎在某些时候出现了偏差。我哪里做错了?

lor*_*rro 6

下面是如何让它编译:

template <class Template, typename... T>
struct type_par_same_as_impl : std::false_type {};

template <template <typename...> class Template, typename... Args>
struct type_par_same_as_impl<Template<Args...>, Args...> : std::true_type {};

template <class Template, typename... Args>
concept type_par_same_as = type_par_same_as_impl<Template, Args...>::value;
Run Code Online (Sandbox Code Playgroud)

std::vector<int>但它实际上不适用于您的测试用例std::vector<int, std::allocator<int>>,并且您只通过了int两者中的一个。所以你需要:

int main()
{

    std::vector<int> vint;
    std::vector<std::string> vstring;
    if constexpr (type_par_same_as<decltype(vint), int, std::allocator<int>>) {
        printf("Vector instantiated with type int!\n");
    }
}
Run Code Online (Sandbox Code Playgroud)