依赖型自动扣除

时间:2017-06-07 14:13:32

标签: c++ c++11 templates template-meta-programming type-deduction

是否可以执行以下操作:

template<class T, T type>
constexpr auto f(/* type used in some way... */) // -> decltype (etc. in case of C++11)
  {
  return std::integral_constant<T,t>{};
  }

constexpr auto z = f(3); // z is deduced as an integral_constant<int,3>;

肯定不可能使用运行时值,但在这种情况下3是编译时值。也许有人知道我不知道的一些技巧......

[编辑]   constexpr auto z2 = f&lt; 3&gt;(); //这也没关系

我只想避免重复这种类型..

3 个答案:

答案 0 :(得分:2)

您可以在C ++ 17中使用auto模板参数:

template <auto T>
constexpr auto f()
{
    return std::integral_constant<decltype(T), T>{};
}

用法:

f<3>(); // integral_constant<int, 3>

或者,您需要以编译时友好的方式包装您的值:

template <int X>
struct int_ 
{ 
    using type = int;
    static constexpr value = X; 
};

template <typename T>
constexpr auto f(T)
{
    return std::integral_constant<typename T::type, T::value>{};
}

用法:

f(int_<3>{});

答案 1 :(得分:2)

从c ++ 11开始,您可以声明自己的文字(我在这里使用std::index_sequence并且它是c ++ 14,但您可以轻松找到上述的c ++ 11实现):

#include <utility> // for std::index_sequence and std::size_t

constexpr std::size_t ipow(std::size_t base, int exp, std::size_t result = 1) {
  return exp < 1 ? result : ipow(base*base, exp/2, (exp % 2) ? result*base : result);
}

constexpr std::size_t vdot(std::index_sequence<>, std::index_sequence<>) {
    return 0;
}

template <std::size_t C, std::size_t... Cs, std::size_t I, std::size_t... Is>
constexpr std::size_t vdot(std::index_sequence<C, Cs...>, std::index_sequence<I, Is...>) {
    return C*ipow(10, I) + vdot(std::index_sequence<Cs...>{}, std::index_sequence<Is...>{});
}

template <char... Cs>
std::integral_constant<std::size_t, vdot(std::index_sequence<static_cast<std::size_t>(Cs - '0')...>{}, std::make_index_sequence<sizeof...(Cs)>{})> operator ""_ic() {
    return {};
}

int main() {
   auto ic = 3_ic;
   static_cast<void>(ic);
}

[live demo]

答案 2 :(得分:1)

在C ++ 11和C ++ 14中,根据

,这是不可能的

§14.8.2.5[temp.deduct.type] 13和14

  

无法从非类型的类型推断出模板类型参数   模板参数。 [例如:

template<class T, T i> void f(double a[10][i]); 
int v[10][20]; 
f(v); // error: argument for template-parameter T cannot be deduced 
  

-end example]

所以你被迫指定一个类型。例如f<int, 3>(/*...*/)

我完全赞同@Barry教我in his answer to my last question

Demo