Vor*_*ord 3 c++ templates specialization template-specialization function-templates
这是一个最小的代码示例,展示了我正在尝试的工作原理,但不是我希望的工作方式:
#include <string>
#include <type_traits>
#include <iostream>
struct string_tag {
using R=const std::string;
};
struct int_tag {
using R=const int;
};
template <bool TS>
class Wibble {
public:
template<typename TAG>
typename TAG::R getValue(TAG);
};
template <bool TS>
template <typename TAG>
typename TAG::R Wibble<TS>::getValue(TAG) {
if constexpr (std::is_same<TAG, string_tag>::value) {
return "hello";
}
if constexpr (std::is_same<TAG, int_tag>::value) {
return 42;
}
}
// instantiate classes
template class Wibble<true>;
template class Wibble<false>;
int main () {
Wibble<true> tw;
Wibble<false> fw;
std::cout << "tw string: " << tw.getValue(string_tag{}) << std::endl;
std::cout << "tw int: " << tw.getValue(int_tag{}) << std::endl;
std::cout << "fw string: " <<fw.getValue(string_tag{}) << std::endl;
std::cout << "fw int: " << fw.getValue(int_tag{}) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我想要更改的部分是包含所有constexpr逻辑的丑陋的函数模板定义。我希望能够TAG独立定义不同的专业化,但这样做会给我带来redefinition of ...错误。
像下面这样的语法会很好:
template<bool TS>
template<>
string_tag::R Wibble<TS>::getValue(string_tag) {
return "hello";
}
Run Code Online (Sandbox Code Playgroud)
但电脑说“不”。
我想了一下,阅读了语言规范等,然后我想到了以下事情:
\n为了特化成员函数模板,类模板必须特化。时期。这是无法用概念来克服的,或者至少我还没有找到方法。我想您不想为每种 TS 情况复制代码。也许可以使用一些 Alexandrescu 风格的元编程技术自动完成,但我无法立即想到任何事情。
\n重载而不是模板是一个很好的选择,但我猜你希望能够将它们添加到线外,而不是在类内部......
\n然后我想起 David Wheeler:\xe2\x80\x9c 计算机科学中的所有问题都可以通过另一级间接来解决。”所以让我们添加一个:
\nnamespace detail\n{\ntemplate<typename TAG> auto getValue(TAG);\n\ntemplate<>\nauto getValue<string_tag>(string_tag)\n{\n return "hi";\n}\n\n\ntemplate<>\nauto getValue<int_tag>(int_tag)\n{\n return 42;\n}\n\ntemplate<>\nauto getValue<double_tag>(double_tag)\n{\n return 1324.2;\n}\n\n}\n\ntemplate<bool TS>\ntemplate<typename TAG>\nauto Wibble<TS>::getValue(TAG t)\n{\n return detail::getValue(t);\n}\nRun Code Online (Sandbox Code Playgroud)\nhttps://godbolt.org/z/GsPK4MP8M \n希望有帮助。
\n