c++ - 两种模板示例有什么区别?
问题描述
我打算让一个“MyVector”类具有 3D 坐标(X、Y、Z)。
我尝试使构造函数具有三种类型的函数参数,每种参数类型都满足 std::is_arithmetic。
我做了两个不同的代码。一个运行良好,但另一个不工作。
这是我的代码。
主文件
#include <iostream>
#include "MyVector.h"
using namespace std;
int main()
{
MyVector mv1 = MyVector();
int x = 5;
double y = 2.0;
float z = 5.0;
MyVector mv2 = MyVector(z, y, x);
//MyVector mv3 = MyVector(&x);
cout << boolalpha << is_arithmetic<int>::value << endl;
cout << mv2;
}
我的向量.h
#pragma once
#include <type_traits>
#include <iostream>
class MyVector
{
public:
MyVector();
MyVector(const MyVector&);
//This is What I wanted
template <typename N1, typename = std::enable_if_t<std::is_arithmetic<N1>::value >
, typename N2, typename = std::enable_if_t<std::is_arithmetic<N2>::value >
, typename N3, typename = std::enable_if_t<std::is_arithmetic<N3>::value > >
MyVector(const N1& x, const N2& y, const N3& z)
{
X = x;
Y = y;
Z = z;
}
//Working
template <typename N, typename = std::enable_if_t<std::is_arithmetic<N>::value >>
MyVector(const N& x)
{
X = 0;
Y = 0;
Z = 0;
}
//Not Working
template <typename N, std::enable_if_t<std::is_arithmetic<N>::value >>
MyVector(const N& x)
{
X = 0;
Y = 0;
Z = 0;
}
private:
float X;
float Y;
float Z;
public:
friend std::ostream& operator<<(std::ostream&, const MyVector&);
};
我不知道下面两个代码有什么区别
1. template <typename N, typename = std::enable_if_t<std::is_arithmetic<N>::value >>
2. template <typename N, std::enable_if_t<std::is_arithmetic<N>::value >>
解决方案
这两行代码的操作方式略有不同:
template <typename N, typename = std::enable_if_t<std::is_arithmetic<N>::value
// or with name
template <typename N, typename second = std::enable_if_t<std::is_arithmetic<N>::value
将类型定义为模板(在第一种情况下未命名)并提供默认值 ( std::enable_if...
)。这归结为<N=int, second=int>
你的情况。
这篇文章有助于理解在哪里使用模板/类型名。然而
2. template <typename N, std::enable_if_t<std::is_arithmetic<N>::value >>
有一个非类型模板参数。这归结<N=int, enable_if<...>::type second=?>
为两个版本之间的主要区别以及一个版本“工作”开箱即用的原因是,这一次,此非类型模板假定的值默认情况下未指定。您需要指定它或编写类似的东西
3. template <typename N, std::enable_if_t<std::is_arithmetic<N>::value >* = nullptr>
以下版本是等效的,但提供了一个名称:
4. template <typename N, std::enable_if_t<std::is_arithmetic<N>::value >* second = nullptr>
TLDR
在第二种情况下,您还必须指定enable-if
守卫的默认值,编译器无法推断(或在调用时指定两个模板参数,这是不希望的)。编译器错误提示如果该行(不工作)没有与上面的第 (3) 行交换:
/home/juli/te.cc:37:5: note: candidate: ‘template<class N, typename std::enable_if<std::is_arithmetic<_Tp>::value, void>::type <anonymous> > MyVector::MyVector(const N&)’
37 | MyVector(const N& x)
| ^~~~~~~~
/home/juli/te.cc:37:5: note: template argument deduction/substitution failed:
/home/juli/te.cc:63:30: note: couldn’t deduce template parameter ‘<anonymous>’
63 | MyVector mv3 = MyVector(x);
根据您使用的标准,研究新引入concepts
的功能c++2a
可能会很有趣。
推荐阅读
- python - Pyrosm 加载节点和边 - 输入必须是有效的几何对象
- memory-leaks - Ryzen 7 2700X 上的 HAXM 启动错误 - 系统崩溃原因的线索?
- webgl - 如何为浮点纹理设置数据?
- wordpress - Docker 容器动态主机文件
- nginx-ingress - NGINX 入口控制器正在崩溃
- html - div 元素中的数据属性并在 ::after 伪元素上显示
- coq - coq中的模简化
- html - 如何在 HTML CSS 和 asp.net mvc 中的表格内打开表格
- restructuredtext - reStructuredText 中的`..print` 有什么作用?
- asp.net - 如何通过 asp.net 项目中的 Seed 传递 FK 的值