带有模板参数的 C++ 友元函数 enable_if
C++ friend function with a template argument enable_if
我正在为一个结构的友元函数苦苦挣扎,该结构的模板参数为 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 */
和
// 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 version 11.0.3 (clang-1103.0.32.59)
。)
我希望运算符 + 仅适用于具有相同模板参数的类型,例如,foo 仅适用于 foo,但不适用于 foo 或 foo。
我认为这与 密切相关,但我很难弄清楚如何解决我的问题。
我尝试了很多模板定义,例如 tempate<typename T, typename>
、tempate<typename T>
、tempate<typename T, typename = typename std::enable_if...>
,但是 none 这些工作。
如代码中所述,在体内定义是可行的,但我想了解如何使用具有类型特征的模板友元函数。
任何帮助将不胜感激!
友元声明引用了非模板运算符,而class定义之外的定义引用了模板运算符,它们不匹配。
你可能想要
// 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);
}
我正在为一个结构的友元函数苦苦挣扎,该结构的模板参数为 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 */
和
// 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 version 11.0.3 (clang-1103.0.32.59)
。)
我希望运算符 + 仅适用于具有相同模板参数的类型,例如,foo 仅适用于 foo,但不适用于 foo 或 foo。
我认为这与 tempate<typename T, typename>
、tempate<typename T>
、tempate<typename T, typename = typename std::enable_if...>
,但是 none 这些工作。
如代码中所述,在体内定义是可行的,但我想了解如何使用具有类型特征的模板友元函数。 任何帮助将不胜感激!
友元声明引用了非模板运算符,而class定义之外的定义引用了模板运算符,它们不匹配。
你可能想要
// 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);
}