C++ 在模板中输入条件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6251889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:46:25  来源:igfitidea点击:

Type condition in template

c++templatesconditional

提问by Congelli501

Is it possible to build only some part of the code given the type of the template in C++ ? It would be something lake that :

给定 C++ 中的模板类型,是否可以仅构建部分代码?这将是一个湖:

#include <iostream>

using namespace std;

template<typename T>
void printType(T param)
{
    #if T == char*
        cout << "char*" << endl;
    #elif T == int
        cout << "int" << endl;
    #else
        cout << "???" << endl;
    #endif
}

int main()
{
    printType("Hello world!");
    printType(1);
    return 0;
}

采纳答案by Wormer

Since C++17 there is a way to do exactly this with if-constexpr. The following compiles since clang-3.9.1, gcc-7.1.0, and recent MSVC compiler 19.11.25506 handles well too with an option /std:c++17.

从 C++17 开始,有一种方法可以使用 if-constexpr 做到这一点。以下编译自 clang-3.9.1、gcc-7.1.0 和最近的 MSVC 编译器 19.11.25506 也使用选项 /std:c++17 处理得很好。

#include <iostream>
#include <type_traits>

template<typename T>
void printType(T)
{
    if constexpr (std::is_same_v<T, const char*>)
        std::cout << "const char*" << std::endl;
    else if constexpr (std::is_same_v<T, int>)
        std::cout << "int" << std::endl;
    else
        std::cout << "???" << std::endl;
}

int main()
{
    printType("Hello world!");
    printType(1);
    printType(1.1);
    return 0;
}

Output:

输出:

const char*
int
???

回答by Xeo

Type traits:

类型特征:

#include <iostream>
#include <type_traits> // C++0x
//#include <tr1/type_traits> // C++03, use std::tr1

template<typename T>
void printType(T param)
{
  if(std::is_same<T,char*>::value)
        std::cout << "char*" << endl;
  else if(std::is_same<T,int>::value)
        std::cout << "int" << endl;
  else
        std::cout << "???" << endl;
}

Or even better yet, just overload the function:

或者更好的是,只需重载函数:

template<class T>
void printType(T partam){
  std::cout << "???" << endl;
}

void printType(char* partam){
  std::cout << "char*" << endl;
}

void printType(int partam){
  std::cout << "int" << endl;
}

Partial ordering will take care that the correct function is called. Also, overloading is preferred to template specialization in the general case, see thisand this articefor why. Might not apply for you if you totally have to print the type, as implicit conversions are considered for overloaded functions.

部分排序将注意调用正确的函数。此外,在一般情况下,重载优于模板特化,请参阅本文本文了解原因。如果您完全必须打印类型,则可能不适用于您,因为重载函数会考虑隐式转换。

回答by Alexander Gessler

Use template specialization:

使用模板特化:

template<typename T>
void printType(T param)
{
   // code for the general case - or omit the definition to allow only the specialized types
}

template<>
void printType<char*>(char* param)
{
   // code for char*
}

template<>
void printType<int>(int param)
{
   // code for int    
}

// ...

回答by Puppy

You can use a specialization. The preprocessor runs before all templates and cannot interact with them.

您可以使用专业化。预处理器在所有模板之前运行,不能与它们交互。

template<typename T> void printType(T t) {
    std::cout << typeid(T).name(); // fallback
}
template<> void printType<char*>(char* ptr) {
    std::cout << "char*";
}
template<> void printType<int>(int val) {
    std::cout << "int";
}

回答by Jesse Emond

You use template specificationto specify versions of your function to work differently based on its type. For example, you can make a generic version of a function that would work with most types, and make a specific version for e.g. intthat will be faster. You'd do it this way:

您可以使用模板规范来指定函数的版本,以根据其类型进行不同的工作。例如,您可以制作一个适用于大多数类型的函数的通用版本,并为 eg 制作一个特定的版本,int这样会更快。你会这样做:

template <class T>
void printType(T param)
{
    cout<<"Generic version"<<endl;
}
template <>
void printType<int>(int param)
{
    cout<<"Int version"<<endl;
}
template <>
void printType<char>(char param)
{
    cout<<"Char version"<<endl;
}
//Rince and repeat.