当前位置: 首页 > 知识库问答 >
问题:

带有模板参数enable\U if的C friend函数

南宫天逸
2023-03-14

我正在努力使用一个结构的友元函数,该结构有一个模板参数,如果

// foo.h
#ifndef FOO_H
#define FOO_H
#include <type_traits>

template<
    typename T,
    typename = typename std::enable_if<std::is_arithmetic<T>::value>::type
>
struct foo {
    foo(T bar) : bar(bar) {}

    T get() { return bar; }

    friend foo operator+(const foo& lhs, const foo& rhs);
    // Defining inside a body works:
    // {
    //     return foo(lhs.bar + rhs.bar);
    // }

private:
    T bar;
};

// None of these work:
// tempate<typename T, typename>
// tempate<typename T>
// tempate<typename T, typename = void>
template<
    typename T,
    typename = typename std::enable_if<std::is_arithmetic<T>::value>::type
>
foo<T> operator+(const foo<T>& lhs, const foo<T>& rhs)
{
    return foo<T>(lhs.bar + rhs.bar);
}
#endif /* ifndef FOO_H */

// main.cpp
#include <iostream>
#include "foo.h"

int main()
{
    foo<int> f{1};
    foo<int> g{2};
    std::cout << (f + g).get() << '\n';
    return 0;
}

如果尝试编译,则会出现以下链接器错误:

Undefined symbols for architecture x86_64:
  "operator+(foo<int, void> const&, foo<int, void> const&)", referenced from:
      _main in main-5fd87c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

(带有Apple clang版本11.0.3(clang-1103.0.32.59)。)

我希望操作符只处理具有相同模板参数的类型,例如,foo只处理foo,而不处理foo或foo。

我认为这与这个问题密切相关,但我很难弄清楚如何解决我的问题。我尝试了许多模板定义,如temate

正如代码中注释的那样,在主体中定义是有效的,但我想学习如何使用具有类型特征的模板朋友函数。任何帮助都将不胜感激!


共有1个答案

蒋畅
2023-03-14

友元声明引用非模板运算符,而类定义之外的定义引用模板运算符,但它们不匹配。

你可能会想要

// forward declaration of the class template
template<
    typename T,
    typename X = typename std::enable_if<std::is_arithmetic<T>::value>::type
>
struct foo;

// declaration of the operator template
template<
    typename T,
    typename = typename std::enable_if<std::is_arithmetic<T>::value>::type
>
foo<T> operator+(const foo<T>& lhs, const foo<T>& rhs);

// definition of the class template
template<
    typename T,
    typename
>
struct foo {
    foo(T bar) : bar(bar) {}

    T get() { return bar; }

    friend foo operator+<T>(const foo& lhs, const foo& rhs);
    // or left the template parameters to be deduced as
    friend foo operator+<>(const foo& lhs, const foo& rhs);

private:
    T bar;
};

//definition of the operator template
template<
    typename T,
    typename
>
foo<T> operator+(const foo<T>& lhs, const foo<T>& rhs)
{
    return foo<T>(lhs.bar + rhs.bar);
}

现场直播

 类似资料:
  • 是否允许在友元声明中为模板参数提供默认值? Visual Studio 2015似乎允许这样做。gcc拒绝了。我在cppreference页面上找不到任何内容。

  • 问题内容: 我正在向Django的模板传递一个函数,该函数返回一些记录。我想调用此函数并遍历其结果。 那不行 我试图将函数的返回值设置为变量并遍历该变量,但是似乎没有办法在Django模板中设置变量。 有什么正常的方法吗? 问题答案: 你不能调用在模板中需要参数的函数。写一个模板标签或过滤器。

  • 我希望维护语法,但似乎只能将typenames放在括号中,而不能将类放在括号中。以下是我当前的代码: 问题1:我找不到一种方法来使“default”参数对于特殊化不是必需的。我尝试了使用默认构造函数的代理类,将第三个参数更改为指针,并指定nullptr(这在语法上并不理想)和对类型的常量引用(这仍然需要用户端的三个参数),但似乎没有任何东西允许在中接受两个参数。 问题2:我找不到正确的语法来获得混

  • 如果我没有理解错的话,类模板定义了一个函数,所以当我调用时,编译器有可能进行隐式强制转换,但是在函数模板的情况下,此时没有函数定义,所以隐式强制转换不会发生。 但我不明白为什么编译器不能创建函数定义,然后应用隐式强制转换? 错误是: 在函数“int main()”中:    25:24:错误:调用“test2::add(void(&)(int))”没有匹配函数    25:24:注:候选人是:  

  • 我正在尝试创建一个模板函子,它将使用任意数量的参数作为参数对象和成员函数。我不知道如何用模板正确地编写代码。 如果我使对象::方法没有参数-代码编译。但是有参数-没有。 严重性代码描述项目文件行抑制状态错误C2664'int Builder::运算符()(T

  • 我正在使用执行REST调用,并且我有一个包含斜杠(即20/20)的uriparam > 如果我不执行httpEncoder,我将获得一个rest调用:http://www.nowhere.com/?variable=20/20,值变量gets仅为20。 如果我执行httpEncoder,变量的值是%2f(它是正确的,这是我想要的值),但是当我执行其余的调用时,它会调用:http://www.now