Kos*_*nov 9 c++ templates template-specialization c++11 c++14
是否可以在C++ 11/14中编写类似的内容?
#include <iostream>
#include <vector>
template <typename T>
T Get();
template <typename T>
struct Data {
std::vector<T> data;
};
template <>
template <typename T>
Data<T> Get<Data<T>>() {
return Data<T>{{T{}, T{}}};
}
template <>
template <typename T>
std::vector<T> Get<std::vector<T>>() {
return std::vector<T>(3);
}
int main() {
std::cout << Get<Data<int>>().data.size() << std::endl; // expected output is 2
std::cout << Get<std::vector<int>>().size() << std::endl; // expected output is 3
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,重载将无济于事,因为调用Get<...>()将是不明确的(请参阅参考资料):
template <typename T>
Data<T> Get() {
return Data<T>{{T{}, T{}}};
}
template <typename T>
std::vector<T> Get() {
return std::vector<T>(3);
}
Run Code Online (Sandbox Code Playgroud)
关于如何克服这个问题的任何方向都是受欢
有一个解决方法,它给你这样的东西:不专门 - 重载:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
template <typename T>
size_t Get(const T& data)
{
return 444;
}
template <typename T>
struct Data
{
std::vector<T> data;
};
template <typename T>
size_t Get(const Data<T>& data) {
return data.data.size();
}
int main() {
std::cout << Get<>(0) << std::endl; // expected output is 444
std::cout << Get<>(Data<int>{}) << std::endl; // expected output is 0
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
444
0
Run Code Online (Sandbox Code Playgroud)
注意,这size_t Get(const Data<T>& data)不是一个特殊化 - 它完全是"不同的" Get(),它被称为Data<T>任何类型的参数T.
在这里你可以看到工作样本.
编辑
我看到你完全改变了你的问题.但是,我仍然会尝试回答它.缺少部分函数专业化有一个标准的解决方法 - 使用委托给结构/类.
这是你需要的:
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
struct GetImpl;
template <typename T>
struct Data {
std::vector<T> data;
};
template <typename T>
struct GetImpl< Data<T> >
{
static Data<T> Get() {
return Data<T>{ {T{}, T{}} };
};
};
template <typename T>
struct GetImpl< std::vector<T> >
{
static std::vector<T> Get() {
return std::vector<T>(3);
};
};
int main() {
std::cout << GetImpl< Data<int> >::Get().data.size() << std::endl; // expected output is 2
std::cout << GetImpl< std::vector<int> >::Get().size() << std::endl; // expected output is 3
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
2
3
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢语法,可以通过将静态函数更改Get()为函数调用运算符来使其更短一些:
template <typename T>
struct Get< Data<T> >
{
Data<T> operator()() {
return Data<T>{ {T{}, T{}} };
};
};
template <typename T>
struct Get< std::vector<T> >
{
std::vector<T> operator()() {
return std::vector<T>(3);
};
};
Run Code Online (Sandbox Code Playgroud)
然后:
Get< Data<int> >()().data.size();
Get< std::vector<int> >()().size();
Run Code Online (Sandbox Code Playgroud)
你只有两个额外的角色 - ().这是我能想到的最短的解决方案.
正如Columbo在他的评论中提到的那样,您应该应用标准的解决方法,因为缺少对函数的部分特化支持:委派给部分专门的类:
template <typename T>
struct GetImpl;
template <typename T>
T Get() { return GetImpl<T>::Do(); }
Run Code Online (Sandbox Code Playgroud)
现在使用部分特化struct GetImpl<T> { static T Do(); }而不是Get<T>()