Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板化函数的部分typedef(`using`)_C++_Templates_Typedef_C++14_Using - Fatal编程技术网

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
vs
dot(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
vs
dot(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
的默认值。