【问题标题】:C++: template specialization, std map choosing wrong specializationC++:模板特化,std map 选择了错误的特化
【发布时间】:2018-10-30 16:45:32
【问题描述】:

我有一个基于 stl 类型调用其他模板的模板。使用 map<int, int> 工作正常,但是,如果我用 map<int, std::string> 调用专业化,它会选择通用专业化,而不是地图专业化。如何确保任何类型的地图(<int, int><int, string> 等)都能选择正确的专业?

基本上是这样的,A类使用了两个特质来专精

template<typename T, typename P=trait<T>>
class A{
public
    typedef P traits
  //

    A(T a, T b){}

    static T foo(T a, T b){
        T d = traits::foo(a,b)
    }
};

特征:

template<typename T>
struct trait{
    static T foo(T a, T b){
        //do something
    }
};

template<typename T>
struct trait<std::map<T,T> >{
    static std::map<T,T> foo(std::map<T,T> a, std::map<T,T> b){
        //do something
    }
};

主要:

std::map<int, std::string> a = {{1,"a"},{2,"b"}}
std::map<int, std::string> b = {{3,"c"},{4,"d"}}
A some_name(a,b);
some_name.foo(a,b);

【问题讨论】:

  • 你能提供一个minimal reproducible example吗?这些只是模板,但我猜你在某个地方实例化了它们
  • 使用两个模板参数而不是一个,即template &lt;class Key, class Value&gt;?
  • 我没有得到这个关闭。这个问题很清楚,昆汀在短短两分钟内就想出了解决方案(尽管在 cmets 中,我不同意,但是哦,好吧)。当然,提供的代码虽然最少且可验证,但并不完整,但 MCVE 并不是真正的要求,而是更多的建议。
  • @CássioRenan 问题的标准应该比“某人字面上有可能凭直觉得到答案”要高很多。 MCVE 是一个非常好的栏 - “我的代码不起作用,这里是演示我的问题的示例代码”比“我的代码不起作用,这是一个片段,如果你知道如何填写这些点”你自己,最终可能会证明一个问题可能是也可能不是我的实际问题”
  • @Barry 这不是对某些问题的直觉,可能是也可能不是 OP 正在寻找的问题。从他的问题中可以清楚地看出他的问题是什么,以及他需要做些什么来解决它。这就是我不同意关闭的原因。毕竟,我们有可回答的问题不正是适度的重点吗?这是可以回答的。

标签: c++ templates c++17 traits


【解决方案1】:

地图的key和value可以使用不同的模板参数:

template<typename K, V>
struct trait<std::map<K,V> >{
    static std::map<K,V> foo(std::map<K,V> a, std::map<K,V> b){
        //do something
    }
};

但问题在于,对于具有自定义比较类或自定义分配器的地图,它将失败:

A<std::map<int, int>>  // specialization for std::map
A<std::map<int, float>> // specialization for std::map
A<std::map<int, float, std::greater<int>>> // generic. Oops.

因此,您最好的选择实际上是使用可变参数模板进行专业化:

template<typename... Ts>
struct trait<std::map<Ts...> >{
    static std::map<Ts...> foo(std::map<Ts...> a, std::map<Ts...> b){
        //do something
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多