C++ C++;:模板专门化,std映射选择错误的专门化

C++ C++;:模板专门化,std映射选择错误的专门化,c++,templates,c++17,traits,C++,Templates,C++17,Traits,我有一个根据stl类型调用其他模板的模板。使用map可以很好地工作,但是,如果我使用map调用专门化,它会选择泛型专门化,而不是map专门化。我如何确保任何类型的映射(,等等)选择正确的专门化 基本上看起来是这样的,A类使用两种特性来专门化 template<typename T, typename P=trait<T>> class A{ public typedef P traits // A(T a, T b){} static T

我有一个根据stl类型调用其他模板的模板。使用map
可以很好地工作,但是,如果我使用map
调用专门化,它会选择泛型专门化,而不是map专门化。我如何确保任何类型的映射(
等等)选择正确的专门化

基本上看起来是这样的,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)
    }
};
模板
甲级{
平民的
typedefp性状
//
A(ta,tb){}
静态T foo(T a,T b){
td=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
    }
};
模板
结构特征{
静态T foo(T a,T b){
//做点什么
}
};
样板
结构特征{
静态std::map foo(std::map a,std::map b){
//做点什么
}
};
大体上:

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);
std::map a={{1,“a”},{2,“b”}
映射b={3,“c”},{4,“d”}
A某个名称(A,b);
一些名字是foo(a,b);

您可以为映射的键和值使用不同的模板参数:

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
    }
};
模板
结构特征{
静态std::map foo(std::map a,std::map b){
//做点什么
}
};
但问题是,对于具有自定义比较类或自定义分配器的映射,它将失败:

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.
A//std::map的专门化
std::map的//专门化
A/通用。哎呀。
因此,您的最佳选择实际上是使用可变模板进行专门化:

template<typename... Ts>
struct trait<std::map<Ts...> >{
    static std::map<Ts...> foo(std::map<Ts...> a, std::map<Ts...> b){
        //do something
    }
};
模板
结构特征{
静态std::map foo(std::map a,std::map b){
//做点什么
}
};

能否请您提供一份详细信息?这些只是模板,但我想你可以实例化它们,使用两个模板参数而不是一个,即
模板
?我不明白这个闭包。问题很清楚,昆汀在短短两分钟内就提出了解决方案(尽管在评论中,我不同意,但很好)。当然,提供的代码虽然很小且可验证,但并不完整,但MCVE并不是一个真正的要求,而是一个建议。@CássioRenan一个问题的标准应该比“某人可以凭直觉找到答案”要高一些。MCVE是一个非常好的标准-“我的代码不起作用,这里是演示我的问题的示例代码”比“我的代码不起作用,这里是一个片段,如果你自己弄清楚如何填充这些点,最终可能会演示一个问题,这个问题可能是我的实际问题,也可能不是我的实际问题。”“@Barry这并不是对某个问题的直觉,这个问题可能不是OP想要的。从他的问题中可以清楚地看出,他的问题是什么,他需要做些什么来解决它。这就是为什么我不同意这个结论。毕竟,我们有可回答的问题,这不是温和的全部意义吗?这是有责任的。