Her*_*ton 2 c++ templates template-function variadic-templates c++11
我正在尝试使函数接受不同的参数,具体取决于枚举.
// cake.h
#pragma once
#include <utility>
enum class TYPE { CupCake, Jelly, BirthdayCake };
struct cake_tin { /* etc etc */ };
/** Fills in different ingredients for different types of cake */
template <TYPE, typename ...Args>
void fill_tin(cake_tin &tin, Args... args);
/** Bakes a cake */
template <TYPE type, typename ...Args>
void bake_cake(Args&&...args) {
cake_tin tin;
fill_tin<type>(tin, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
.cpp文件包含该函数的特化
// cake.cpp
#include "cake.h"
// If I put this in cake.h, I get multiple definition error (since the template's fully specalised), but if I move this to the .cpp file, I get undefined reference when I compile
template <>
void fill_tin<TYPE::CupCake>(cake_tin &tin, int cherries) {
// ... etc etc
}
template <>
void fill_tin<TYPE::Jelly>(cake_tin &tin, bool wobble) {
// ... etc etc
}
Run Code Online (Sandbox Code Playgroud)
为了完整
// main.cpp
#include "cake.h"
int main() {
bake_cake<TYPE::CupCake>(1);
}
Run Code Online (Sandbox Code Playgroud)
包含的另一个文件 cake.h
// other.cpp
#include "cake.h"
Run Code Online (Sandbox Code Playgroud)
编译 clang++ -Wall -Wextra -std=c++11 main.cpp other.cpp -o main
我已经尝试过申报
template <> void fill_tin<TYPE::CupCake>(cake_tin &tin, int cherries);
template <> void fill_tin<TYPE::Jelly>(cake_tin &tin, bool wobble);
Run Code Online (Sandbox Code Playgroud)
仍然无法实例化该模板.如果我将特化项移动到标题中,那么当标题包含在链接阶段的多个编译单元中时,它们将导致重新定义.
我的问题是:我怎样才能使这个工作,或者有更好的方法来做到这一点?
尝试将模板专业化与函数重载混合总是非常痛苦.
提供类模板特化:
template<TYPE> struct tin_filler; // undefined
template<> struct tin_filler<TYPE::CupCake> {
void operator()(cake_tin& tin, int cherries); };
template<> struct tin_filler<TYPE::Jelly> {
void operator()(cake_tin& tin, bool wobble); };
template <TYPE type, typename ...Args>
void bake_cake(Args&&...args) {
cake_tin tin;
tin_filler<type>()(tin, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
或者使用integral_constant到的具体化TYPE和正常使用函数重载:
void fill_tin(std::integral_constant<TYPE, TYPE::CupCake>, cake_tin& tin, int cherries);
void fill_tin(std::integral_constant<TYPE, TYPE::Jelly>, cake_tin& tin, bool wobble);
template <TYPE type, typename ...Args>
void bake_cake(Args&&...args) {
cake_tin tin;
fill_tin(std::integral_constant<TYPE, type>(), tin, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
前者更为一般,但在这种情况下,后者可能更清晰,更简单.
| 归档时间: |
|
| 查看次数: |
542 次 |
| 最近记录: |