是否可以执行以下操作:
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;(); //这也没关系
我只想避免重复这种类型..
答案 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);
}
答案 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