为什么在匿名命名空间中定义模板时出现内部链接错误?
Why internal linkage error when template defined in anonymous namespace?
在匿名命名空间中声明模板导致错误 error: function '(anonymous namespace)::f<std::__1::vector<float, std::__1::allocator<float> > >' has internal linkage but is not defined
。
代码如下:
#include <type_traits>
#include <vector>
namespace {
template <class T>
void f(const T& data);
template <>
void f<int>(const int& data){}
template <typename Iterable, typename std::decay<decltype(*std::begin(std::declval<Iterable>()))>::type>
void f(const Iterable& data) {
;
}
}
void g() {
std::vector<float> x;
f(x);
}
我搜索找到了,但是不会解释
更新:
如果我删除匿名命名空间,错误将变为 Undefined symbols for void f<std::__1::vector<float, std::__1::allocator<float> > >(std::__1::vector<float, std::__1::allocator<float> > const&
.
您有两个重载的模板函数 f
,第二个有两个模板参数。 f(x);
将调用确实未在任何地方定义的 void f(const T& data);
。
我现在将草拟一个简短的解决方案。
最实用的方法是使用部分特化的助手 class,因为模板函数不能部分特化。
#include <type_traits>
#include <vector>
#include <iostream>
namespace {
template<typename T, typename=void>
struct ff;
template<>
struct ff<int, void> {
static constexpr bool specialized=true;
static inline void func(const int &data)
{
std::cout << "int" << std::endl;
}
};
template<typename T>
struct ff<T,
std::void_t<decltype(*std::begin(std::declval<T>()))>> {
static constexpr bool specialized=true;
static inline void func(const T &data)
{
std::cout << "vector" << std::endl;
}
};
template <class T, typename=decltype(ff<T>::specialized)>
inline void f(const T& data)
{
ff<T>::func(data);
}
}
int main()
{
std::vector<float> x;
int y;
f(x); // Result: vector
f(y); // Result: int
// Error:
//
// char *z;
// f(z);
}
出于 SFINAE 的目的,您仍然需要模板函数的第二个模板参数,并且大多数编译器应该在适度的优化级别上优化掉额外的函数调用。
在匿名命名空间中声明模板导致错误 error: function '(anonymous namespace)::f<std::__1::vector<float, std::__1::allocator<float> > >' has internal linkage but is not defined
。
代码如下:
#include <type_traits>
#include <vector>
namespace {
template <class T>
void f(const T& data);
template <>
void f<int>(const int& data){}
template <typename Iterable, typename std::decay<decltype(*std::begin(std::declval<Iterable>()))>::type>
void f(const Iterable& data) {
;
}
}
void g() {
std::vector<float> x;
f(x);
}
我搜索找到了
更新:
如果我删除匿名命名空间,错误将变为 Undefined symbols for void f<std::__1::vector<float, std::__1::allocator<float> > >(std::__1::vector<float, std::__1::allocator<float> > const&
.
您有两个重载的模板函数 f
,第二个有两个模板参数。 f(x);
将调用确实未在任何地方定义的 void f(const T& data);
。
我现在将草拟一个简短的解决方案。
最实用的方法是使用部分特化的助手 class,因为模板函数不能部分特化。
#include <type_traits>
#include <vector>
#include <iostream>
namespace {
template<typename T, typename=void>
struct ff;
template<>
struct ff<int, void> {
static constexpr bool specialized=true;
static inline void func(const int &data)
{
std::cout << "int" << std::endl;
}
};
template<typename T>
struct ff<T,
std::void_t<decltype(*std::begin(std::declval<T>()))>> {
static constexpr bool specialized=true;
static inline void func(const T &data)
{
std::cout << "vector" << std::endl;
}
};
template <class T, typename=decltype(ff<T>::specialized)>
inline void f(const T& data)
{
ff<T>::func(data);
}
}
int main()
{
std::vector<float> x;
int y;
f(x); // Result: vector
f(y); // Result: int
// Error:
//
// char *z;
// f(z);
}
出于 SFINAE 的目的,您仍然需要模板函数的第二个模板参数,并且大多数编译器应该在适度的优化级别上优化掉额外的函数调用。