0

I'm trying to use templates to generify a method. However I'm struggling to match string types like string char * literals. See the following code example:

template<typename ValueType>
void match_data_type(ValueType value) {
    if constexpr (std::is_same_v<std::remove_cvref_t<ValueType>, bool>) {
        std::cout << "bool" << std::endl;
    } else if constexpr (std::is_same_v<std::remove_cvref_t<ValueType>, char>) { // Useless?
        std::cout << "char" << std::endl;
    } else if constexpr (std::is_same_v<std::remove_cvref_t<ValueType>, char *>) {
        std::cout << "char *" << std::endl;
    } else if constexpr (std::is_same_v<std::remove_cvref_t<ValueType>, char[]>) { // Useless?
        std::cout << "char[]" << std::endl;
    } else if constexpr (std::is_same_v<std::remove_cvref_t<ValueType>, std::string>) {
        std::cout << "std::string" << std::endl;
    } else {
        std::cout << "Not matched!" << std::endl;
    }
}

Test cases:

match_data_type(false);
char *string_buffer = "Text";
match_data_type(string_buffer);
match_data_type("Test");
std::string standard_string = "Test";
match_data_type(standard_string);

Output:

bool
char *
Not matched!
std::string

The surprising part to me is the Not matched! output since I passed a string literal directly into the method and it didn't match any of the cases.

1)Is there any constexpr check which matches all types of char *? Then I need another case for std::string objects so I can pass the .c_str() into the respective legacy method which expects char * as its argument.

2) Is there a way to statically fail the compilation if none of the cases are matched? (e.g. the else branch is taken). static_assert(false) in the else branch does not work since it will always take effect, regardless of the passed parameter type.

4

1 回答 1

4

字符串文字是常量。

的类型"hello"char const[6],它会衰减(因为你按值取值)到char const*. 您必须对此进行检查,而不是char*.


对于其余的代码,char检查并不是无用的(您当然可以调用match_data_type('c')),但检查char[]是——参数永远不会有数组类型,因为它是一个值。

更广泛地说,除非您明确提供该参数,否则std::remove_cvref_t<ValueType>它将始终是公正的——因为该类型永远不会被推断为引用类型或具有限定符。ValueType

于 2020-11-16T20:11:27.517 回答