以下代码在CentOS 7上的g++8.1.0下无法编译:
嘿。h
#pragma once
#include <iostream>
#include <type_traits>
class Valid {};
class Invalid {};
struct Hey
{
template<typename T>
static constexpr bool is_valid() { return std::is_same_v<T, Valid>; }
template<typename T, std::enable_if_t<is_valid<T>()>* = nullptr>
void howdy() const;
};
template<typename T, std::enable_if_t<Hey::is_valid<T>()>*>
void Hey::howdy() const
{
std::cout << "Howdy" << std::endl;
}
编译器输出:
In file included from hey.cpp:1:
hey.h:18:8: error: no declaration matches âvoid Hey::howdy() constâ
void Hey::howdy() const
^~~
hey.h:14:10: note: candidate is: âtemplate<class T, std::enable_if_t<is_valid<T>()>* <anonymous> > void Hey::howdy() constâ
void howdy() const;
^~~~~
hey.h:8:8: note: âstruct Heyâ defined here
struct Hey
^~~
令人惊讶的是,要正确编译并获得所需的行为,我所要做的就是在Hey:
嘿.h(固定,跳过前几行无聊的内容)
struct Hey
{
template<typename T>
static constexpr bool is_valid() { return std::is_same_v<T, Valid>; }
template<typename T>
using EnableType = std::enable_if_t<is_valid<T>()>;
template<typename T, EnableType<T>* = nullptr>
void howdy() const;
};
template<typename T, Hey::EnableType<T>*>
void Hey::howdy() const
{
std::cout << "Howdy" << std::endl;
}
嘿,cpp
#include "hey.h"
int main(int, char**)
{
Hey hey;
hey.howdy<Valid>();
// Adding this line breaks the build, as it should:
// hey.howdy<Invalid>();
return 0;
}
经过多次调整,我将编译器错误的范围缩小到1)
is_valid()
是
Hey
和2)
howdy()
在内部声明
嘿
的身体,但定义在外面。如果删除
using
使
是否有效()
外部的独立函数
嘿
,编译时没有问题。如果删除
使用
并定义
你好()
在类定义中,编译也没有问题。但是当
你好()
在类定义之外定义,
是否有效()
在类定义内声明,并且
使用
不存在,编译器将失败。这是正确的行为吗?我在看编译器错误吗?