C++ 模板化函数的部分typedef(`using`)
为了使用模板实现点积函数,我编写了以下模板函数C++ 模板化函数的部分typedef(`using`),c++,templates,typedef,c++14,using,C++,Templates,Typedef,C++14,Using,为了使用模板实现点积函数,我编写了以下模板函数 template <typename T, typename R = float, typename = std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>, typename = std::enable_if_t<std::is_arithmetic<decltype(std::
template <typename T, typename R = float,
typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>,
typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>>
constexpr R dot(const T a_vector, const T b_vector)
{
return a_vector.x * b_vector.x + a_vector.y * b_vector.y;
}
此代码生成
- 在g++
错误中:“点”未命名类型
- 在clang++
和中,错误:应为类型
错误:应为';'别名声明后
我是否可以选择使用替代功能?答案非常简单:
template <class T1, class T2> void foo();
template <class T1, class T2> struct FooHelper {
static constexpr auto foo = &foo<T1, T2>;
};
template <class T>
auto food = FooHelper<T, float>::foo;
void g() {
food<float>();
}
模板void foo();
模板结构FooHelper{
静态constexpr auto foo=&foo;
};
模板
自动食物=食物助手::食物;
void g(){
食物();
}
答案很简单:
template <class T1, class T2> void foo();
template <class T1, class T2> struct FooHelper {
static constexpr auto foo = &foo<T1, T2>;
};
template <class T>
auto food = FooHelper<T, float>::foo;
void g() {
food<float>();
}
模板void foo();
模板结构FooHelper{
静态constexpr auto foo=&foo;
};
模板
自动食物=食物助手::食物;
void g(){
食物();
}
您可以翻转模板参数的顺序。如果您将R
放在第一位,用户可以很容易地为其提供不同的类型(如果他们需要的话):
template <
typename R = float,
typename T,
typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>,
typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>>
constexpr R dot(const T a_vector, const T b_vector)
{
return a_vector.x * b_vector.x + a_vector.y * b_vector.y;
}
模板<
typename R=浮点,
类型名T,
类型名称=
std::如果启用,则启用,
类型名称=
std::如果>
常数表达式R点(常数a_向量,常数b_向量)
{
返回a_向量.x*b_向量.x+a_向量.y*b_向量.y;
}
然后dot(a,b)
给你一个float
vsdot(a,b)
给你一个double
。我发现dot
比查找dotd
的含义要清楚得多
不过,如果您使用的是C++14,最好干脆完全删除
R
模板参数,然后返回auto
只需翻转模板参数的顺序即可。如果您将R
放在第一位,用户可以很容易地为其提供不同的类型(如果他们需要的话):
template <
typename R = float,
typename T,
typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>,
typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>>
constexpr R dot(const T a_vector, const T b_vector)
{
return a_vector.x * b_vector.x + a_vector.y * b_vector.y;
}
模板<
typename R=浮点,
类型名T,
类型名称=
std::如果启用,则启用,
类型名称=
std::如果>
常数表达式R点(常数a_向量,常数b_向量)
{
返回a_向量.x*b_向量.x+a_向量.y*b_向量.y;
}
然后dot(a,b)
给你一个float
vsdot(a,b)
给你一个double
。我发现dot
比查找dotd
的含义要清楚得多
不过,如果您使用的是C++14,最好干脆完全删除
R
模板参数,然后返回auto
只能为类型创建类型别名。函数不是一个类型。@Dundee,是的,您是这样做的!:)看看我的答案。你还没有在任何地方使用R
。。。您是否打算使用constexpr dot(…)
?如果您仍然需要类型推断,只需添加一个新的function@Simon克雷默-没错。粘贴旧代码。我会修好的。但是,错误仍然存在。只能为类型创建类型别名。函数不是一个类型。@Dundee,是的,您是这样做的!:)看看我的答案。你还没有在任何地方使用R
。。。您是否打算使用constexpr dot(…)
?如果您仍然需要类型推断,只需添加一个新的function@Simon克雷默-没错。粘贴旧代码。我会修好的。然而,错误依然存在。为什么不使用变量模板呢?那么为什么不使用autofood=&foo代码>?@PiotrSkotnicki,没有任何理由!我实际上是在想可变模板,开始做,然后意识到它不是必需的,但类仍然留在我的大脑中!!!将编辑。谢谢你指出这一点。这不符合OP的要求-食物的第一个参数也不再是模板。@Puppy,对。返回带有变量模板的帮助器。然而,我觉得你对自己的否决票有点高兴。为什么不使用可变模板呢?那么为什么不使用autofood=&foo代码>?@PiotrSkotnicki,没有任何理由!我实际上是在想可变模板,开始做,然后意识到它不是必需的,但类仍然留在我的大脑中!!!将编辑。谢谢你指出这一点。这不符合OP的要求-食物的第一个参数也不再是模板。@Puppy,对。返回带有变量模板的帮助器。然而,我觉得你对你的落选票有点高兴。是的,我知道。我只是想我可以把它进一步缩短为dotd()。auto的问题是,它不能优雅地处理所有类型。假设传入的向量是int类型。在这种情况下,dot()函数不会返回任何有意义的值。@Dundee为什么返回类型没有意义?如果x
s和y
s是int
,您将得到int
。这怎么会比浮动更糟糕呢?见鬼,我刚刚意识到,这件事没有什么区别。哈哈,我想昨天我的脑子太累了。谢谢你指出这一点,巴里:)你根本不需要t
的默认值。是的,我知道这一点。我只是想我可以把它进一步缩短为dotd()。auto的问题是,它不能优雅地处理所有类型。假设传入的向量是int类型。在这种情况下,dot()函数不会返回任何有意义的值。@Dundee为什么返回类型没有意义?如果x
s和y
s是int
,您将得到int
。这怎么会比浮动更糟糕呢?见鬼,我刚刚意识到,这件事没有什么区别。哈哈,我想昨天我的脑子太累了。谢谢你指出这一点,巴里:)你根本不需要t
的默认值。