简体   繁体   English

C++ 朋友 function 与模板参数 enable_if

[英]C++ friend function with a template argument enable_if

I'm struggling with a friend function for a struct that has a template argument with enable_if :我正在与朋友 function 为一个带有enable_if模板参数的结构而苦苦挣扎:

// 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 */

and

// 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;
}

If I try to compile, get the following linker error:如果我尝试编译,得到以下 linker 错误:

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)

(with Apple clang version 11.0.3 (clang-1103.0.32.59) .) (使用Apple clang version 11.0.3 (clang-1103.0.32.59) 。)

I want the operator + to only work with types with the same template arguments, eg, foo only with foo, but not with foo or foo.我希望运算符 + 仅适用于具有相同模板 arguments 的类型,例如,foo 仅适用于 foo,而不适用于 foo 或 foo。

I think this is closely related to this question , but I'm having a hard time trying to figure out how to solve my problem.我认为这与这个问题密切相关,但我很难弄清楚如何解决我的问题。 I tried many template definitions like tempate<typename T, typename> , tempate<typename T> , tempate<typename T, typename = typename std::enable_if...> but none of these work.我尝试了许多模板定义,例如tempate<typename T, typename>tempate<typename T>tempate<typename T, typename = typename std::enable_if...>但这些都不起作用。

As commented in the code, defining inside a body works, but I want to learn how to work with template friend functions with type traits.如代码中所述,在主体内部定义是可行的,但我想学习如何使用具有类型特征的模板友元函数。 Any help would be greatly appreciated!任何帮助将不胜感激!

The friend declaration refers to a non-template operator, while the definition out of the class definition refers to a template one, they don't match.朋友声明是指非模板运算符,而 class 定义中的定义是指模板之一,它们不匹配。

You might want你可能想要

// 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);
}

LIVE居住

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM