2016-12-16 88 views
3

下面的示例代码说明我的问题:如何专门用可变参数类模板

#include <array> 
#include <vector> 
#include <iostream> 
#include <type_traits> 

namespace Vector 
{ 
    namespace Intern 
    { 
     template <typename T1, typename ...T2> 
     struct Traits; 

     // How can I specialize here so that Memory is being assigned properly?? 
     template <typename T1, int N> 
     struct Traits<T1, int> { 
      static constexpr bool Static = 1; 
      using Memory = std::array<T1, N>; 
     }; 

     template <typename T1> 
     struct Traits<T1> { 
      static constexpr bool Static = 0; 
      using Memory = std::vector<T1>; 
     }; 
    } 

    template <typename T1, typename ...T2> 
    class Object 
    { 
     public : 
      void printd() 
      { 
       std::cout << "Is Static: " << Traits::Static << std::endl; 
      } 
     private: 
      using Traits = Intern::Traits<T1, T2...>; 
      using Memory = typename Traits::Memory; 

      Memory m_memory; 
    }; 

    template <typename T1, typename ...T2> 
    static auto Create(T2&& ...ln) -> decltype(auto) 
    { 
     return new Object<T1, T2...>(); 
    } 
} 

int main() 
{ 
    auto static_vector = Vector::Create<int>(10); 
    static_vector->printd(); 

    auto active_vector = Vector::Create<int>(); 
    active_vector->printd(); 
} 

我想知道我可以专注性状结构,这样的类型存储器进行适当的分配为标准::在上面的例子中,N设为10。

+0

你想static_vector的类型是什么呢? –

+0

你想如何在这里推出'N'?为什么你需要一个可变模板而不是简单的两个参数? – Holt

回答

1

您不能直接使用整数,但可以将整数包装为一个类型。这可以使用例如 例如std::integral_constant

template <typename T1, typename T2, int N> 
struct Traits<T1, std::integral_constant<T2, N>> { 
    static constexpr bool Static = 1; 
    using Memory = std::array<T1, N>; 
}; 

template <typename T1> 
struct Traits<T1> { 
    static constexpr bool Static = 0; 
    using Memory = std::vector<T1>; 
}; 


auto static_vector = Vector::Create<int, std::integral_constant<int, 10>>(); 
+0

这接近我正在寻找的解决方案。然而,有没有像你使用std :: integral_constant的方式,但不改变Vector :: Create函数的签名?换句话说,是否可以通过扩展此代码来实现,以便我可以保留Vector :: Create (10)签名? – vixiv

+1

@vixiv我不这么认为。我不熟悉'constexpr'提供了什么(不使用支持它的编译器),但我猜测一旦你在函数参数land中,就不会返回模板参数。或者用户定义的文字可能会有,但这会改变语法。 – Angew

1

保持简单:

#include <array> 
#include <vector> 
#include <iostream> 
#include <type_traits> 

namespace Vector 
{ 
    struct VariableSize {}; 
    template<std::size_t N> struct FixedSize {}; 

    template<typename T, std::size_t N> 
    auto Create(FixedSize<N>) 
    { 
     return std::array<T, N>(); 
    } 

    template<typename T, std::size_t N> 
    auto Create(VariableSize) 
    { 
     return std::vector<T>(); 
    } 
} 

int main() 
{ 
    auto static_vector = Vector::Create<int>(Vector::FixedSize<10>()); 

    auto active_vector = Vector::Create<int>(Vector::VariableSize()); 
} 
+0

你的代码确实很简单。但事实是,我希望在一些后端代码中重新设置因子(优化内存分配),而不必更改面向前端的Vector :: Create签名。 – vixiv

+1

@vixiv恐怕这是不可能的。你不能通过改变它的参数来改变函数的返回值的类型。甚至没有'constexpr'函数可以做到这一点。 –