2015-10-08 89 views
0

我想实现一个模板化函数,以便函数只接受某些特定类型的输入。我试过std :: enable_if和std :: is_base_of来实现目标。简化代码如下所示。代码编译并在启用C++ 11时使用clang ++或g ++运行。但是,当我用Visual Studio 2013进行编译时,它总是说could not deduce template argument for 'is_base_class'。谁能告诉我为什么Visual Studio 2013不能编译以及如何解决这个问题?为什么模板化的C++函数不能在Visual Studio 2013下编译

#include <type_traits> 
#include <map> 
#include <unordered_map> 
#include <iostream> 

using namespace std; 

template <class Type> 
struct TypeWrapper {}; 

template <class T0, class T1> 
struct CompoundType : public TypeWrapper<T0>, public TypeWrapper<T1> {}; 

template <class Type, 
    typename std::enable_if< 
     std::is_base_of< 
      TypeWrapper<Type>, 
      CompoundType< 
       std::map<typename Type::key_type, typename Type::mapped_type>, 
       std::unordered_map<typename Type::key_type, typename Type::mapped_type> 
      > 
     >::value 
     , Type 
    >::type* is_base_class = nullptr 
> 
void TemplatedFunction(Type map) { 
    std::cout << "Hello, world!" << std::endl; 
} 

int main(int argc, char *argv[]) 
{ 
    std::unordered_map<int, double> a; 
    TemplatedFunction(a); 
} 
+0

你能减少示例代码任何进一步的?另外,如果你希望人们(包括你自己)琢磨它的结构,请一致缩进。 –

+1

FYI - VS2015正常工作。 – Blacktempel

+0

VS 2013中的SFINAE支持有问题。除了迁移到2015年,您可能没有任何工作。 – bpeikes

回答

0

一个解决:

template <typename T, 
      typename K = typename T::key_type, 
      typename V = typename T::mapped_type> 
struct rebind_to_unordered_map 
{ 
    using type = std::unordered_map<K, V>; 
}; 

template <typename T, 
      typename K = typename T::key_type, 
      typename V = typename T::mapped_type> 
struct rebind_to_map 
{ 
    using type = std::map<K, V>; 
}; 

template <class Type> 
typename std::enable_if< 
     std::is_base_of< 
      TypeWrapper<Type>, 
      CompoundType< 
       typename rebind_to_map<Type>::type, 
       typename rebind_to_unordered_map<Type>::type 
      > 
     >::value 
     , void 
    >::type 
TemplatedFunction(const Type&) { 
    std::cout << "Hello, world!" << std::endl; 
} 

甚至

template <class Type, 
      typename K = typename Type::key_type, 
      typename V = typename Type::mapped_type, 
      typename std::enable_if< 
      std::is_base_of< 
       TypeWrapper<Type>, 
       CompoundType<std::map<K, V>, std::unordered_map<K, V> 
      > 
     >::value 
     , Type 
    >::type* is_base_class = nullptr 
> 
void TemplatedFunction(Type map) { 
    std::cout << "Hello, world!" << std::endl; 
} 
+0

解决了我的问题,谢谢。我更喜欢第二种解决方案。 – user2621037

相关问题