Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是C++;模板类型匹配与基类引用不匹配,如何使其与基类引用匹配? 这是我的C++程序代码< /p> #include <iostream> #include <memory> using namespace std; template <typename T> struct A { T x; }; template <typename T> struct B:A<T> { }; template <typename T> void func(const A<T>& t) { cout<<"2"<<endl; } template <typename T> void func(const T& t) { cout<<"1"<<endl; } int main() { B<int> b; func(b); } #包括 #包括 使用名称空间std; 模板 结构A{tx;}; 模板 结构B:A{}; 模板 无效函数(常数A&t){ 库特解1_C++_Templates_Matching - Fatal编程技术网

为什么是C++;模板类型匹配与基类引用不匹配,如何使其与基类引用匹配? 这是我的C++程序代码< /p> #include <iostream> #include <memory> using namespace std; template <typename T> struct A { T x; }; template <typename T> struct B:A<T> { }; template <typename T> void func(const A<T>& t) { cout<<"2"<<endl; } template <typename T> void func(const T& t) { cout<<"1"<<endl; } int main() { B<int> b; func(b); } #包括 #包括 使用名称空间std; 模板 结构A{tx;}; 模板 结构B:A{}; 模板 无效函数(常数A&t){ 库特解1

为什么是C++;模板类型匹配与基类引用不匹配,如何使其与基类引用匹配? 这是我的C++程序代码< /p> #include <iostream> #include <memory> using namespace std; template <typename T> struct A { T x; }; template <typename T> struct B:A<T> { }; template <typename T> void func(const A<T>& t) { cout<<"2"<<endl; } template <typename T> void func(const T& t) { cout<<"1"<<endl; } int main() { B<int> b; func(b); } #包括 #包括 使用名称空间std; 模板 结构A{tx;}; 模板 结构B:A{}; 模板 无效函数(常数A&t){ 库特解1,c++,templates,matching,C++,Templates,Matching,您可以使用std::enable_if和模板化模板参数来更好地匹配函数,如: #include <iostream> #include <memory> #include <type_traits> using namespace std; template <typename T> struct A { T x; }; template <typename T> struct B:A<T> { }; templa

您可以使用
std::enable_if
和模板化模板参数来更好地匹配函数,如:

#include <iostream>
#include <memory>
#include <type_traits>

using namespace std;

template <typename T>
struct A { T x; };

template <typename T>
struct B:A<T> {  };

template <template <typename...> typename T, typename ...Args, typename = std::enable_if_t<std::is_base_of_v<A<Args...>, T<Args...>>>>
void func(const T<Args...>& t) {
    cout<<"2"<<endl;
}

template <typename T>
void func(const T& t) {
    cout<<"1"<<endl;
}


int main() {
    B<int> b;
    func(b);
    func(5);
}
这再也不行了

解决方案2 基于,您可以创建更通用的类型特征。与解决方案1一样,此解决方案对其模板参数没有限制

namespace detail 
{
    template <template <typename...> typename Base>
    struct template_base_detector
    {
        template <typename... Args>
        constexpr std::true_type operator()(Base<Args...>*);
        constexpr std::false_type operator()(...);
    };
} 

template <template <typename...> typename Base, typename T>
struct is_template_base_of 
    : decltype(std::declval<detail::template_base_detector<Base>>()((T*)nullptr)) {};

// since C++ 14
template <template <typename...> typename Base, typename T>
constexpr bool is_template_base_of_v = is_template_base_of<Base, T>::value;
C++ 11和14 我们必须退回到标签发送:

namespace detail 
{
    template <typename T>
    void func(std::true_type, const T& t) 
    {
        std::cout << 2 << endl;
    }

    template <typename T>
    void func(std::false_type, const T& t) 
    {
        std::cout << 1 << endl;
    }
}

template <typename T>
void func(const T& t) 
{
    detail::func(is_template_base_of<A, T>{}, t);
}
namespace details{
  template <typename T>
  void func(std::true_type,const A<T>& t) {
    std::cout<<"2"<<std::endl;
  }

  template <class T>
  void func(std::false_type,const T& t) {
    std::cout<<"1"<<std::endl;
  }
}

template <typename T>
void func(const T& t) {
  details::func(has_template_base<A,T>,t);
}
名称空间详细信息
{
模板
无效函数(标准::真值类型,常数T&T)
{
std::cout标签调度

首先,我们编写一个trait来检测是否有模板作为基础:

namespace details {
  template<template<class...>class Z>
  struct htb {
    template<class...Ts>
    constexpr std::true_type operator()(Z<Ts...>*){return {};}
    constexpr std::false_type operator()(...){return {};}
  };
}
template<template<class...>class Z, class X>
constexpr inline auto has_template_base = details::htb<Z>{}((X*)nullptr);
名称空间详细信息{
模板
结构htb{
模板
constexpr std::true_类型运算符()(Z*){return{};}
constexpr std::false_类型运算符()(…){return{};}
};
}
模板
constexpr inline auto具有_template_base=details::htb{}((X*)nullptr);
现在,我们可以使用新特性标记dispatch:

namespace detail 
{
    template <typename T>
    void func(std::true_type, const T& t) 
    {
        std::cout << 2 << endl;
    }

    template <typename T>
    void func(std::false_type, const T& t) 
    {
        std::cout << 1 << endl;
    }
}

template <typename T>
void func(const T& t) 
{
    detail::func(is_template_base_of<A, T>{}, t);
}
namespace details{
  template <typename T>
  void func(std::true_type,const A<T>& t) {
    std::cout<<"2"<<std::endl;
  }

  template <class T>
  void func(std::false_type,const T& t) {
    std::cout<<"1"<<std::endl;
  }
}

template <typename T>
void func(const T& t) {
  details::func(has_template_base<A,T>,t);
}
名称空间详细信息{
模板
无效函数(标准::真实类型,常数A&t){

std::coutFor
void func(const T&T)
T
被推断为
B
void func(const B&T)
void func(const a&T)
更匹配。我应该如何更改它以使其匹配
void func(const a&T)
?您可以为每个派生类编写代理重载,例如
模板void func(const B&t){func(static_cast(t));}
。这听起来合理吗?所有派生类是否都遵循相同的模式:
模板结构派生:A
?谢谢,您的建议在这种情况下很有帮助。
A
有许多子类。在我的程序中,有许多类似于
模板void func2(const A&p1,const A&p2)的地方
。如果我使用代理重载,由于笛卡尔积,许多代理重载都必须编写。奇怪的是,当添加另一层()时,特定于问题的解决方案不起作用。但是,这些特性……我理解类型特性是如何工作的,但是编译器如何在
操作符()中推断出
Ts…
?只需查看
X
(从
has_template_base
)的类型层次结构,@Timo-template-argument推导就可以对一个类型及其基类型应用?最终,它将
a*
a*
进行测试,并将
{Ts..
推断为
{int}
@StoryTeller这种含糊不清的说法有点让人痛苦。我发誓我已经让它起作用了,但我现在遇到了问题。我正在否定这种解决方案。